IO流
I是指Input(输入),O是指Output(输出)。
在Java中,文件的输入和输出是通过流(Stream)来实现的,流的概念源于Unix中管道(pipe)的概念。在Unix系统中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等。
一个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是Internet上的某个URL。对于流而言,我们不用关心数据是如何传输的,只需要向源端输入数据,向目的端获取数据即可。
流按照处理数据的单位,可以分为字节流和字符流;按照流向分为输入流和输出流(注意:输入流和输出流都是站在程序的角度参照的)。
字节流
字节流用于处理以字节为单位的二进制文件(如音乐、图片等)
InputStream
InputStream抽象类是所有输入字节流类的直接或间接父类,FileInputStream是其重要子类:
FileInputStream常用构造方法:
FileInputStream(File file) :通过File对象创建FileInputStream对象。
FileInputStream(String name) :通过文件(非“目录”)路径创建FileInputStream对象。
FileInputStream常用方法:
int read():从输入流中读取单个字节的数据;如果已到达文件末尾,则返回 -1。
int read(byte[] b):从输入流中将最多b.length个字节的数据读入一个byte数组中,以整数形式返回存入数组中的实际字节个数;如果已到达文件末尾,则返回 -1。
void close():关闭此文件输入流并释放与此流有关的所有系统资源。
OutputStream
OutputStream抽象类是所有输出字节流类的直接或间接父类,FileOutputStream是其重要子类:
FileOutputStream常用构造方法:
FileOutputStream(File file) :通过File对象创建FileOutputStream对象。
FileOutputStream(String name) :通过文件(非“目录”)路径创建FileOutputStream对象。
FileOutputStream(File file, boolean append):通过File对象创建FileOutputStream对象;第二个参数如果为true ,则字节将被写入文件的末尾而不是开头。
FileOutputStream常用方法:
void write(int b):将指定的单个字节数据写入此文件输出流。
void write(byte[] b, int off, int len):将byte数组中从off开始的len个字节写入此文件输出流。
void flush():刷新字节输出流并强制写出缓冲内所有字节数据。 void close():关闭此文件输出流并释放与此流有关的所有系统资源。
字节流例子1:单个字节进行传输(由于程序运行次数频繁,所以速度较慢):
//D盘文件复制到F盘
File a = new File("D:\\1.txt");
File b = new File("F:\\1.txt");
//输入流:通过File对象创建FileInputStream对象,作为输入流的通信通道
FileInputStream inputStream = new FileInputStream(a);
//输出流:通过File对象创建FileOutputStream对象,作为输出流的通信通道
FileOutputStream outputStream = new FileOutputStream(b);
//利用read方法读取单个字节的数据到输入流
int data = 0;//这里定义一个int变量用于判断文件字节是否输入完,当data等于-1时完成字节输入
while ((data=inputStream.read())!=-1){
//利用write方法将指定的单个字节数据写入输出流,即在F盘创建文件并写入。
outputStream.write(data);
}
outputStream.flush();//将输出流中缓冲的数据强制写出,就是字节在传输过程中会在缓冲中有遗留
//关闭传输管道并释放资源
outputStream.close();
inputStream.close();
字节流例子2:利用数组的方式,即将读取的单个字节先放入一个准备好的数组在进行传输进行传输(程序运行次数少,速度很快):
//D盘文件复制到F盘
File a = new File("D:\\1.txt");
File b = new File("F:\\1.txt");
FileInputStream inputStream = new FileInputStream(a);
FileOutputStream outputStream = new FileOutputStream(b);
//定义一个数组,用来存放单个字节,数组的大小不宜过大
byte[] car = new byte[1024];
//定义一个int变量第一个作用是判断文件是否被取完,第二个是控制从数组中取出多少数据
int length;
while ((length=inputStream.read())!=-1){
//这里用了重写后的write方法,即从car数组中从0开始到length个字节写入输出流
outputStream.write(car,0,length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
字符流
Java虚拟机将字节转化为2个字节的Unicode字符就形成了字符流,字符流用于处理以Unicode字符为单位的文本文件(如记事本文件等)。
Reader
Reader抽象类是所有输入字符流类的直接或间接父类, FileReader是其重要子类:
FileReader常用构造方法:
FileReader(File file) :通过File对象创建FileReader对象。
FileReader(String fileName) :通过文件(非“目录”)路径创建FileReader对象。
FileReader常用方法:
int read():从输入流中读取单个字符的数据,如果已到达流的末尾,则返回 -1 。
int read(char[] cbuf):从输入流中将最多cbuf.length个字符的数据读入一个char数组中,以整数形式返回存入数组中的实际字节个数,如果已到达流的末尾,则返回 -1 。
void close():关闭此文件输入流并释放与此流有关的所有系统资源。
Writer
Writer抽象类是所有输出字符流类的直接或间接父类,FileWriter是其重要子类:
FileWriter常用构造方法:
FileWriter(File file) :通过File对象创建FileWriter对象。
FileWriter(String fileName) :通过文件(非“目录”)路径创建FileWriter对象。
FileWriter(File file, boolean append):通过File对象创建FileWriter对象;第二个参数如果为true ,则字节将被写入文件的末尾而不是开头。
FileWriter常用方法:
void write(int c):将指定的单个字符数据写入此文件输出流。
void write(char[] cbuf, int off, int len):将char数组中从off开始的len个字符写入此文件输出流。
void flush():刷新字符输出流缓冲。 void close():关闭此文件输出流并释放与此流有关的所有系统资源
字符流例子1:(逐个读取字符流中的字符,一个一个的进行传输,速度较慢):
FileReader reader = new FileReader("D:\\1.txt");
FileWriter writer = new FileWriter("F:\\1.txt");
int data;
while ((data=reader.read())!=-1){
writer.write(data);
}
writer.flush();
writer.close();
reader.close();
字符流例子2:(先将逐个读取的字符放到数组中,然后进行传输,速度很快):
FileReader reader = new FileReader("D:\\1.txt");
FileWriter writer = new FileWriter("F:\\1.txt");
int length;
char[] car = new char[1024];
while ((length=reader.read(car))!=-1){
writer.write(car,0,length);
}
writer.flush();
writer.close();
reader.close();
缓冲流
缓冲流是一种装饰器类,目的是让原字节流、字符流新增缓冲的功能以提高读取或写入。
缓冲字节输入流: BufferedInputStream(InputStream in):
缓冲字节输出流: BufferedOutputStream(OutputStream out):
缓冲字符输入流: BufferedReader(Reader in):
缓冲字符输出流: BufferedWriter(Writer out):
制造两个缓冲池,一个在输入流之后,从文件读取数据先放到缓冲池中,一个在输出流之前,从缓冲池中将数据写入输出流,
在两个缓冲池之间的传输会更加高效,减少了扫描源文件的次数。
例子(以字符流为例):
FileReader reader = new FileReader("D:\\1.txt");
//制造输入流缓冲池,连接输入流
BufferedReader bufferedReader = new BufferedReader(reader);
FileWriter writer = new FileWriter("F:\\1.txt");
//制造输出流缓冲池
BufferedWriter bufferedWriter = new BufferedWriter(writer);
//利用数组进行传输,连接输出流
int length;
char [] car = new char[1024];
while ((length=bufferedReader.read(car))!=-1){
bufferedWriter.write(car,0,length);
}
bufferedWriter.flush();
bufferedWriter.close();
bufferedReader.close();
转换流
由于文件自身编码方式和程序运行时使用的默认编码方式不一致,致使程序读取或输出字符文件时可能会出现乱码,这时可以使用字节流操作文件,然后再将字节流转换成字符流,这一转换过程可以借助转换流实现。
InputStreamReader(字节输入流——>字符输入流):
InputStreamReader(InputStream in) :
InputStreamReader(InputStream in, String charsetName):
OutputStreamWriter(字节输出流——>字符输出流):
OutputStreamWriter(OutputStream out) :
OutputStreamWriter(OutputStream out, String charsetName) :
例子(还是以字符流为例):
FileInputStream inputStream = new FileInputStream("D:\\1.txt");
//以UTF-8编码读取文件进入缓冲池
InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
FileOutputStream outputStream = new FileOutputStream("F:\\1.txt");
//以UTF-8编码写入缓冲池
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream,"UTF-8");
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
//利用数组传递方式进行传输
int length;
char [] car = new char[1024];
while ((length=bufferedReader.read(car))!=-1){
bufferedWriter.write(car,0,length);
}
bufferedWriter.flush();
bufferedWriter.close();
bufferedReader.close();