写这个博客,也是在网上看到的一篇帖子,上面有人提问,以前在学习IO流的时候真没去太在意这些,今天自己尝试了一把,确实是有些容易混淆,我在这里给大家总结出来:

我例举的两个对比的列子分别是放在C盘下面的:aaa.txt和aaa.png文件,实现的功能是用IO流读取写入到C盘,得到bbb.txt和bbb.png文件,相当与一个文件的复制功能,实现起来是so easy,可以用到很多方法,只是我这里使用的是字符流和字节流,以及缓冲字符流和缓冲的字节流,大家来看一下:

1、使用缓冲字节流:BufferedInputStream、BufferedOutputStream包装InputStream、OutputStream

1)读取txt文件:

public static void main(String[] args) throws Exception {  		InputStream input=new FileInputStream(new File("C:\\aaa.txt"));  		OutputStream output=new FileOutputStream(new File("c:\\bbb.txt"));  		BufferedInputStream bis=new BufferedInputStream(input);  		BufferedOutputStream bos=new BufferedOutputStream(output);  		byte[] b=new byte[1024];  		while(bis.read(b)!=-1){  			bos.write(b, 0, b.length);  			//必须要添加该方法  			bos.flush();  		}  		  	    input.close();  	    output.close();  	    bis.close();  	    bos.close();  	}

2)读取图片文件

	public static void main(String[] args) throws Exception {  		InputStream input=new FileInputStream(new File("C:\\aaa.png"));  		OutputStream output=new FileOutputStream(new File("c:\\bbb.png"));  		BufferedInputStream bis=new BufferedInputStream(input);  		BufferedOutputStream bos=new BufferedOutputStream(output);  		byte[] b=new byte[1024];  		while(bis.read(b)!=-1){  			bos.write(b, 0, b.length);  			//必须要添加该方法  			bos.flush();  		}  		  	    input.close();  	    output.close();  	    bis.close();  	    bos.close();  	}


上面的代码是一样的,只是文件类型不同,可以发现,都能够成功得到我们想要的结果,记住必须要加BufferedOutputStream中的flush方法,不然结果得不到输出!!

2、使用字符流,InputStreamReader、OutputStreamWriter

1)读取txt文件:

	public static void main(String[] args) throws Exception{  		InputStreamReader input = new InputStreamReader(new FileInputStream(  				new File("C:\\aaa.txt")));  		OutputStreamWriter output = new OutputStreamWriter(  				new FileOutputStream(new File(  						"C:\\bbb.txt")));  		char[] c=new char[1024];  		while(input.read(c)!=-1){  			output.write(c, 0, c.length);  			output.flush();//必须加上这行代码  		}  		input.close();  		output.close();  	}

2)读取图片文件:

	public static void main(String[] args) throws Exception{  		InputStreamReader input = new InputStreamReader(new FileInputStream(  				new File("C:\\aaa.png")));  		OutputStreamWriter output = new OutputStreamWriter(  				new FileOutputStream(new File(  						"C:\\bbb.png")));  		char[] c=new char[1024];  		while(input.read(c)!=-1){  			output.write(c, 0, c.length);  			output.flush();//必须加上这行代码  		}  		input.close();  		output.close();  	}

运行结果会发现:txt文件执行成功,而图片文件生成后里面是空内容,就是不会出现图片;

3、好了,我们再来看一下用缓冲流封装字符流,BufferedReader、BufferedWriter封装InputStreamReader(字符转换流)或者FileReader、OutputStreamWriter(字节转换流)或者FileWriter

1)读取txt文件:

	public static void main(String[] args) throws IOException {  		InputStreamReader input = new InputStreamReader(new FileInputStream(  				new File("C:\\aaa.txt")));  		OutputStreamWriter output = new OutputStreamWriter(  				new FileOutputStream(new File(  						"C:\\bbb.txt")));  		  		BufferedReader br=new BufferedReader(input);  		BufferedWriter bw=new BufferedWriter(output);  		String str=null;  		while((str=br.readLine())!=null){  			bw.write(str);  			bw.flush();//必须加上,否则得不到结果  		}  		  		output.close();  		input.close();  		br.close();  		bw.close();  	}


2)读取图片文件:

	public static void main(String[] args) throws IOException {  		InputStreamReader input = new InputStreamReader(new FileInputStream(  				new File("C:\\aaa.png")));  		OutputStreamWriter output = new OutputStreamWriter(  				new FileOutputStream(new File(  						"C:\\bbb.png")));  		  		BufferedReader br=new BufferedReader(input);  		BufferedWriter bw=new BufferedWriter(output);  		String str=null;  		while((str=br.readLine())!=null){  			bw.write(str);  			bw.flush();//必须加上,否则得不到结果  		}  		  		output.close();  		input.close();  		br.close();  		bw.close();  	}


执行后得到的结果同上一样,txt文件可以得到结果,而图片文件仍然为空!!

我们可以得出这样的结论:

1、因为常见的文件都不是字符流文件,所以用字符流去操作它们可能会不合适,java的API中提到:FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader,所以我们在操作图像数据等字节流的原始数据的时候,请使用字节流,如果文件是字符类数据,我们可以使用字符流,这样可以提高我们的读取效率,最好使用BufferedReader和BufferedWriter,因为它可以直接读取一行!!

2、在使用OutputStreamWriter、或者缓冲流输出的时候,必须加上flush方法,因为flush是清空缓冲区,就是说立即输出到输出目的地,而不是等缓冲区满了再输出,write只是将数据输出到缓冲区,还没有输出到目的地,所以记得加上哦!

3、IO流使用后记得关闭,遵循先开后关原则,否则可能会造成内存溢出现象,养成好的编程习惯!

4、输入流和输出流应保持一致!

希望这篇博客能给你一点帮助!