Java当中的IO流操作大多数都是和文件相关的,见过很多关于IO操作的文章,也许是我自己的理解能力确实很有问题,看起来好像总是不那么清晰,于是我想自己总结一下。
首先必须要了解文件和流的概念。在这里呢,只说明文件的逻辑结构.
(1),按照文件的逻辑结构,可将文件分为两大类:流式文件和记录式文件
流式文件:由字节序列或者字符序列组成。流式文件内的信息不可再划分结构,只是具有顺序关系的一系列字节或字符集合,字节或字符是信息的最小组成单位。例如源程序,文本文档。
记录式文件:记录式文件是一种有结构的文件,它包含若干记录,记录是文件按信息在逻辑上的独立含义划分的一个信息单位,记录在文件中的排列具有顺序关系。记录是文件内独立的最小信息单位。
记录还可以被进一步划分成若干个更小的数据项,数据项是具有标识名的最小的不可分割的数据单位。数据项的集合够成记录,相关记录的集合构成文件。
流式文件可以看成只有一个数据项的记录式文件,而任何记录式文件都可以看成字节流式文件。
(2),流的定义
流是指一组有顺序的,有起点和终点的字节集合,是对数据传输的总称和抽象,也就是说,数据在两个对象之间的传输称之为流。
流的基本操作只有读和写操作,从流中取得数据称为读操作,向流中添加数据的操作称为写操作。
一个流只能进行一种操作,或者读,或者写,不能同时读写。
所以对输入流只能进行读操作,对输出流只能进行写操作。
那么以上的概念应该说说明了很多的问题,可以知道流可以很好的为文件服务,并且流一般都是成对出现。
下面就以最常见和最基本的三种流来做一个说明。
输入流和输出流(FileInputStream FileOutputStream) 每次读或写一个字节
文件字节输入输出流(FileReader FileWriter) 每次读或写一个字符
处理流(缓冲流)(BufferedReader BufferedWriter)
一般来说,前面的两个是属于节点流,是效率很低的方式
处理流事实上是一种通过缓冲而实现的减少读取IO次数的流方式,它可以对上面的两种节点流进行封装,封装后不再以每次读取一个字节或者一个字符为单位,而是采用了一个大约8kb的缓冲区,这样以来效率大大提高了。
下面呢,以一个程序来演示一下三者的用法和效率,这个程序是在linux下的测试。所以请注意在Windows下将目录改为盘符和反双斜杠。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedReaderWriterTest {
public static void main(String[] args) {
BufferedReaderWriterTest test = new BufferedReaderWriterTest();
test.bufferTest();
}
public void bufferTest() {
try {
FileReader fr = new FileReader("/home/tarena/test.txt");
BufferedReader br = new BufferedReader(fr);
//FileWriter fw = new FileWriter("/home/fang/fangfan_io/test.txt");
FileWriter fw = new FileWriter("/home/fang/fangfan_io/test1.txt",true);
BufferedWriter bw = new BufferedWriter(fw);
String s = br.readLine();
while (s != null) {
bw.write(s+"/n");
s=br.readLine();
}
br.close();
fr.close();
bw.close();
fw.close();
System.out.println("Finish!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void testFileOutputInputStream(){
File f = new File ("/home/fang/MyEclipse6.5/myeclipse.txt");
System.out.println(f.exists());
if(f.exists()){
try {
FileInputStream fis = new FileInputStream (f.getAbsolutePath());
FileOutputStream fos =new FileOutputStream("/home/fang/myeclipse.txt");
int b=fis.read();
while(b!=-1){
fos.write(b);
b=fis.read();
}
fis.close();
fos.close();
System.out.println("finish copy file ");
} catch (FileNotFoundException e) {
System.out.println("file is not exist!");
e.printStackTrace();
} catch (IOException e) {
System.out.println("io is error!");
e.printStackTrace();
}
}
}
public void testFileReaderWriterStream(){
File f = new File ("/home/fang/MyEclipse6.5/myeclipse.txt");
System.out.println(f.exists());
if(f.exists()){
try {
FileReader fr = new FileReader (f.getAbsolutePath());
FileWriter fw =new FileWriter("/home/fang/myeclipse.txt");
int b=fr.read();
while(b!=-1){
fw.write(b);
b=fr.read();
}
fr.close();
fw.close();
System.out.println("finish copy file ");
} catch (FileNotFoundException e) {
System.out.println("file is not exist!");
e.printStackTrace();
} catch (IOException e) {
System.out.println("io is error!");
e.printStackTrace();
}
}
}
}
这里呢,试验大文件就可以看出bufferedreader 的效率了,不过我不太赞成,因为后面连个方法比较伤硬盘。