Java IO流

纸上得来终觉浅

1.Java IO流分类:

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

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

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

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

Java IO流_第1张图片

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):

Java IO流_第2张图片


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

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

你可能感兴趣的:(java,IO流,字节流与字符流,输入流与输出流,节点流与处理流)