您的位置:首页 > 编程语言 > Java开发

Java IO流

2016-05-07 19:07 507 查看
纸上得来终觉浅
1.Java IO流分类:

按照流向的不同(以程序为参照,流入程序的为输入流):输入流,输出流 

根据处理数据的单位不同:字节流,字符流

根据角色不同:节点流(直接作用于文件),处理流

所有的流都是基于下面的抽象类:



2.这篇主要讲节点流(访问文件)和处理流,节点流主要是下面四个:

1)FileInputStream 

2)FileOutputStream 

3)FileReader

4)FileWriter

前两个类操作是以字节为单位,后两个类操作是以字符为单位;

5)所有的操作都可以用字节流, 即使是中文也可以(只是用字符流更好),下面是字节流操作中文的一个例子:

package roadArchitectWeb.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test9 {
public static void main(String[] args) {
File file1 = new File("hello1.txt");
File file2 = new File("hello2.txt");
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(file1);
fileOutputStream = new FileOutputStream(file2);
int length;
byte[] b = new byte[1];
while((length=fileInputStream.read(b))!=-1){
fileOutputStream.write(b);
//			fileOutputStream.write("你好".getBytes("UTF-8"));
//			System.out.println("Test9.main():"+new String(b,"UTF-8"));
}
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
hello1.txt:

ab中国
得到的结果是:

hello2.txt:

ab中国
3.解释2中的例子,为什么中文字符经过通过字节流输出到另一个文件还是中文:

1)首先要明确这样一个问题,所有的文件在其中的内容,在内容存在的时候就已经有了一种编码,并且存储在硬盘中,如上例中的hello1,假设它的编码是UTF-8;当用输入流一个字节一个字节的读的时候,并没有破化它存储在硬盘中的顺序,当把这些字节序放入到另一个文件中的时候,这个文件要解析它,我们可以指定一个编码方式对它进行解析,如果我在文件属性中设置了编码,假设为ASCII,它解析的结果肯定不是原来的汉字;如果指定的为UTF-8,就可以解析到。
 所以结论是,字节流当然可以操作包含汉字的文本文件;

2)那为什么经常说不用字节流操作中文文本呢?

因为实际情况是:

A)在输入流中,假设源文件仍然是UTF-8的编码,用FileInputStream读了几个字节,并没有读完,这个时候

我并不知道读的这几个字节能不能正好组成几个汉字,因为源文件是UTF-8编码,汉字是三个字节;你可以说读取的时候三的倍数,如byte[] a = new byte[3],但如果源文件是汉字英文混合呢,所以操作起来要谨慎;

B)相比之下字符流就不会,如果使用FileReader:

采用FileReader一次读取的是汉字的UTF-8的三个字节,然后用一个Char来保存(这个时候UTF-8三个字节的汉字被转化为Unicode的两个字节),或者读取的是一个英文字符的UTF-8的一个字节,然后转化为Unicode的两个字节,也是用一个Char来保存;那么无论读到哪里,Char数组中始终保存的是完整的数据。这其实就是字符流唯一的好处。

示例如下:

fileReader = new FileReader(file1);
fileWriter = new FileWriter(file2);
char[] a = new char[1];
while((fileReader.read(a))!=-1){
fileWriter.write(a);
}


注:输出流的问题,FileWriter输出的时候不能指定编码方式,会使用系统默认的编码方式;这个时候需要使用到转换流(可以指定编码格式),下面会讲到。

4.下面是一个字符串与字符编码的图表(转载自:http://blog.sina.com.cn/s/blog_5920510a0101ijj5.html):



总结:如果想使用字节流完全没有问题,可以在任何情况下使用,即使是文本文件。

5.处理流

BufferedReader,BufferedWriter,BufferedInputStream,BufferedOutputStream分别对应上面的四个类:

用法以BufferedReader,BufferedWriter为例(后面两个用法一样):

package roadArchitectWeb.Test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test9 {
public static void main(String[] args) {
File file1 = new File("hello1.txt");
File file2 = new File("hello2.txt");
FileReader fileReader = null;
FileWriter fileWriter = null;
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
fileReader = new FileReader(file1);
fileWriter = new FileWriter(file2);
bufferedReader = new BufferedReader(fileReader);
bufferedWriter = new BufferedWriter(fileWriter);
String str;
while((str=bufferedReader.readLine())!=null){
bufferedWriter.write(str);
bufferedWriter.flush();
bufferedWriter.newLine();
System.out.println("Test9.main():"+str);
}
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6.转换流

上面说到了,字符流在输出的时候无法设定编码方式,只能使用系统默认的编码方式,下面使用转换流来进行编码转换:

package roadArchitectWeb.Test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Test9 {
public static void main(String[] args) {
File file1 = new File("hello1.txt");
File file2 = new File("hello2.txt");

FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
InputStreamReader inputStreamReader = null;
OutputStreamWriter outputStreamWriter = null;
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;

try {
fileInputStream = new FileInputStream(file1);
fileOutputStream = new FileOutputStream(file2);
inputStreamReader = new InputStreamReader(fileInputStream,"GBK");
outputStreamWriter = new OutputStreamWriter(fileOutputStream,"GBK");
bufferedReader = new BufferedReader(inputStreamReader);
bufferedWriter = new BufferedWriter(outputStreamWriter);
String str;
while((str=bufferedReader.readLine())!=null){
bufferedWriter.write(str);
bufferedWriter.flush();
bufferedWriter.newLine();
System.out.println("Test9.main():"+str);
}
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
bufferedWriter.close();
outputStreamWriter.close();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
bufferedReader.close();
inputStreamReader.close();
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


同时转换流还有这样的功能: 即当知道文本是一种流的时候,还可以使用readline的功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息