以Stream结尾的为字节流,以Writer或者Reader结尾的为字符流。所有的输入流都是抽象类IuputStream(字节输入流)或者抽象类Reader(字符输入流)的子类,所有的输出流都是抽象类OutputStream(字节输出流)或者抽象类Writer(字符输出流)的子类。字符流能实现的功能字节流都能实现,反之不一定。如:图片,视频等二进制文件,只能使用字节流读写。
1、字符流FileReader和FileWriter
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFile {
public static void main(String[] args) throws IOException {
//创建输入流对象
FileReader fr=new FileReader("C:\\Test\\copyfrom.txt");//文件不存在会抛出java.io.FileNotFoundException
//创建输出流对象
FileWriter fw=new FileWriter("C:\\Test\\copyto.txt");
/*创建输出流做的工作:
* 1、调用系统资源创建了一个文件
* 2、创建输出流对象
* 3、把输出流对象指向文件
* */
//文本文件复制,一次读一个字符
method1(fr, fw);
//文本文件复制,一次读一个字符数组
method2(fr, fw);
fr.close();
fw.close();
}
public static void method1(FileReader fr, FileWriter fw) throws IOException {
int ch;
while((ch=fr.read())!=-1) {//读数据
fw.write(ch);//写数据
}
fw.flush();
}
public static void method2(FileReader fr, FileWriter fw) throws IOException {
char chs[]=new char[1024];
int len=0;
while((len=fr.read(chs))!=-1) {//读数据
fw.write(chs,0,len);//写数据
}
fw.flush();
}
}
CopyFile
2、字符缓冲流BufferedReader和BufferedWriter
在读取或者写入文件的时候,先写入或读取到一个缓冲流,这样有助于提高读取和写入的效率
一般的Read或Writer的reader或writer方法是在文件每一个一个字节读取,然后再转换字符,如果用缓冲流会把文件所有内容一起写入缓冲流,再从缓冲流中一起读取出来
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFile2 {
public static void main(String[] args) throws IOException {
//创建输入流对象
BufferedReader br=new BufferedReader(new FileReader("C:\\Test\\copyfrom.txt"));//文件不存在会抛出java.io.FileNotFoundException
//创建输出流对象
BufferedWriter bw=new BufferedWriter(new FileWriter("C:\\Test\\copyto.txt"));
//文本文件复制
char [] chs=new char[1024];
int len=0;
while((len=br.read(chs))!=-1) {
bw.write(chs, 0, len);
}
//释放资源
br.close();
bw.close();
}
}
CopyFile2
3字节流FileInputStream和FileOutputStream
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopImg {
public static void main(String[] args) throws IOException {
FileInputStream fin=new FileInputStream("C:\\Users\\Administrator\\Desktop\\Img.jpg");
FileOutputStream fout=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\ImgCopy.jpg");
int len=0;
byte[] buff=new byte[1024];
while((len=fin.read(buff))!=-1) {
fout.write(buff, 0, len);
}
fin.close();
fout.close();
}
}
4字节缓冲流BufferedInputStream和BufferedOutputStream
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyImg {
public static void main(String[] args) throws IOException {
BufferedInputStream bfin=new BufferedInputStream(new FileInputStream("C:\\Users\\Administrator\\Desktop\\Img.jpg"));
BufferedOutputStream bfout=new BufferedOutputStream(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\ImgCopybuff.jpg"));
int len=0;
byte[] buff=new byte[1024];
while((len=bfin.read(buff))!=-1) {
bfout.write(buff, 0, len);
}
bfin.close();
bfout.close();
}
}
5、转换流:InputStreamReader和OutputStreamWriter
InputStreamReader和OutputStreamWriter是字符和字节的桥梁,也可称之为字符转换流。原理:字节流+编码。
InputStreamReader
nputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
为了达到最高效率,可以考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));//重要
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
/**
* 使用标准输入流,读取键盘录入的数据,存储到项目根目录下的a.txt中
* 将字节输入流转换成字符输入流,InputStreamReader
*/
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
//创建输入流对象
BufferedReader r=new BufferedReader(new InputStreamReader(System.in));
//创建输出流对象
FileWriter fw=new FileWriter("a.txt");
//读写数据
char[] chs=new char[1024];
int len;
while((len=r.read(chs))!=-1) {
fw.write(chs,0,len);
fw.flush();
}
//释放资源
r.close();
fw.close();
}
public static void method2() throws IOException {
//创建输入流对象
InputStream is=System.in;
Reader r=new InputStreamReader(is);
//创建输出流对象
FileWriter fw=new FileWriter("a.txt");
//读写数据
char[] chs=new char[1024];
int len;
while((len=r.read(chs))!=-1) {
fw.write(chs,0,len);
fw.flush();
}
//释放资源
is.close();
fw.close();
}
public static void method1() throws IOException {
//创建输入流对象
InputStream is=System.in;
//创建输出流对象
FileWriter fw=new FileWriter("a.txt");
//读写数据
byte[] bys=new byte[1024];
int len;
while((len=is.read(bys))!=-1) {
fw.write(new String(bys,0,len));
fw.flush();
}
//释放资源
is.close();
fw.close();
}
}
InputStreamReaderDemo
OutputStreamWriter
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));//重要
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
/**
* 读取项目目录下的文件copy.java,并输出到命令行
* 由于标准输出流是字节输出流,所以只能输出字节或者字节数组,但是我们读取到的数据是字符串,如果想进行输出,
* 还需要转换成字节数组(method1)。
* 要想通过标准输出流输出字符串,把标准输出流转换成一种字符输出流即可(method2)。
*/
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//创建输入流
BufferedReader br=new BufferedReader(new FileReader("copy.java"));
//创建输出流
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
String line;//用于接收读到的数据
while((line=br.readLine())!=null) {
bw.write(line);
bw.write("\r\n");
}
br.close();
bw.close();
}
public static void method2() throws FileNotFoundException, IOException {
//创建输入流
BufferedReader br=new BufferedReader(new FileReader("copy.java"));
//创建输出流
//OutputStream os=System.out;
Writer w=new OutputStreamWriter(System.out);//多态,父类引用指向子类对象
String line;//用于接收读到的数据
while((line=br.readLine())!=null) {
w.write(line);
w.write("\r\n");
}
br.close();
w.close();
}
public static void method1() throws FileNotFoundException, IOException {
//创建输入流
BufferedReader br=new BufferedReader(new FileReader("copy.java"));
//创建输出流
OutputStream os=System.out;
String line;//用于接收读到的数据
while((line=br.readLine())!=null) {
os.write(line.getBytes());
os.write("\r\n".getBytes());
}
br.close();
os.close();
}
}
OutputStreamWriterDemo
File类
对目录和文件进行操作
IO流使用规律总结
(1)明确要操作的数据是数据源还是数据目的(要读还是要写)
源:InputStream Reader
目的:OutputStream Writer
(2)明确要操作的设备上的数据是字节还是文本
源:
字节:InputStream
文本:Reader
目的:
字节:OutputStream
文本:Writer
(3)明确数据所在的具体设备
源设备:
硬盘:文件 File开头
内存:数组,字符串
键盘:System.in
网络:Socket
目的设备:
硬盘:文件 File开头
内存:数组,字符串
屏幕:System.out
网络:Socket
(4)明确是否需要额外功能?
需要转换——转换流 InputStreamReader OutputStreamWriter
需要高效——缓冲流Bufferedxxx
多个源——序列流 SequenceInputStream
对象序列化——ObjectInputStream,ObjectOutputStream
保证数据的输出形式——打印流PrintStream Printwriter
操作基本数据,保证字节原样性——DataOutputStream,DataInputStream