Java IO流

来源:互联网 发布:网络推广的工作职责 编辑:程序博客网 时间:2024/05/22 15:05

纸上得来终觉浅

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.处理流

BufferedReaderBufferedWriterBufferedInputStreamBufferedOutputStream分别对应上面的四个类:

用法以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的功能。

0 0