java关于IO流的总结

java的IO流设计的很精巧,其中也涉及了设计模式中的装饰者模式。以此同时,由于IO流所涉及的类相对繁多,很多初学者往往会有或多或少的疑惑,甚至举步维艰,不知道该如何选取适合的流对象来完成相应的功能,很是头疼。看似简单,却不能正确把握要点。

那么,如何正确且快速掌握IO流呢?其实IO流也是有规律可寻的。

首先,先了解一些IO流的基本知识。

知识背景回顾:byte是字节,byte[]是字节数组,char是字符,char[]是字符数据,够详细了吧。接着记住这四个类,传说中的IO的奶爸奶妈。

用于处理字节的两个字节流:InputStream 与 OutputStream。

用于处理字符的两个字符流:Reader 与 Writer。

站在程序的角度,当程序要读入数据的时候,用InputStream字节输入流或者Reader字符输入流。同理,程序要写出数据的时候,用OutputStream字节输出流或者Writer字符输出流。

那么,什么时候用字节流,什么时候用字符流呢?

字节byte,大小8位,字符char,大小16位,等于两个字节,字符是指计算机中使用的字母、数字、字和符号,包括:1、2、3、A、B、C、~!·#¥%……—*()——+等等。

所以知道了以上的知识后,只要是处理文本,汉字等内容的数据,都是使用有关于字符流的类,而当要处理音频文件、图片、歌曲、视频文件等内容的数据,使用字节流来处理。

当我们要开始着手写程序的时候。

1、思考什么方式读什么数据

2、思考程序处理后的数据什么方式写数据

比如:要将硬盘上一个文本文件,复制到硬盘上的另外一个位置。

1、什么方式读什么数据:文件的方式读文本数据,所以使用字符输入流,操作的是文件,选用FileReader。

2、什么方式写数据:文件的方式写文本数据,所以使用字符输出流,操作的是文件,选用FileWriter。

于是有如下代码:

package com.java4fun;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class IOTest {
	public static void main(String[] args) {
		copyFile();
	}

	private static void copyFile() {
		FileReader reader = null;
		FileWriter writer = null;
		try {
			// 建立读入文本,处理文件的字符流
			reader = new FileReader("D:\\log.txt");
			// 建立写出文本,处理文件的字符流
			writer = new FileWriter("D:\\log_copy.txt");
			// 将数据读入后存入字符数据中
			char[] buf = new char[1024];
			int len = 0;
			//当读到结尾时返回-1
			while ((len = reader.read(buf)) != -1) {
				//将数据写出到新的文件
				writer.write(buf,0,len);
				//刷新缓冲区,将数据写入文件中
				writer.flush();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException("未找到要复制的文件");
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("建立复制文件异常");
		} finally {
			try {
				if (reader != null)
					reader.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException("关闭输入流异常");
			}
			try {
				if (writer != null)
					writer.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException("关闭输出流异常");
			}
		}
	}
}
那么,比如:要将硬盘上一个mp3文件,复制到硬盘上的另外一个位置。
1、什么方式读什么数据:文件的方式读非纯文本数据,所以使用字节输入流,操作的是文件,选用FileInputStream。
2、什么方式写数据:文件的方式写非纯文本数据,所以使用字节输出流,操作的是文件,选用FileOutputStream。
于是有如下代码:

package com.java4fun;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class IOTest {
	public static void main(String[] args) {
		copyFile();
	}

	private static void copyFile() {
		FileInputStream input = null;
		FileOutputStream output = null;
		try {
			// 建立读入非纯文本数据,处理文件的字节流
			input = new FileInputStream("D:\\白狐.mp3");
			// 建立写出非纯文本数据,处理文件的字节流
			output = new FileOutputStream("D:\\狐白.mp3");
			// 将数据读入后存入字节数组中
			byte[] buf = new byte[1024];
			int len = 0;
			//当读到结尾时返回-1
			while ((len = input.read(buf)) != -1) {
				//将数据写出到新的文件
				output.write(buf,0,len);
				//刷新缓冲区,将数据写入文件中
				output.flush();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException("未找到要复制的文件");
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("建立复制文件异常");
		} finally {
			try {
				if (input != null)
					input.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException("关闭输入流异常");
			}
			try {
				if (output != null)
					output.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException("关闭输出流异常");
			}
		}
	}
}

么,又如:要将键盘录入的数据,以文件的形式保存到硬盘。
1、什么方式读什么数据:字节数据,所以使用字节输入流,可是我们要以文本的形式存储,所以使用字节转字符的转换字符输入流,InputStreamReader
2、什么方式写数据:文件的方式写文本数据,所以使用字符输出流,操作的是文件,选用FileWriter。
于是有如下代码:

package com.java4fun;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

public class IOTest {
	public static void main(String[] args) {
		copyFile();
	}

	private static void copyFile() {
		InputStreamReader isr = null;
		FileWriter fw = null;
		try {
			// 读进来的是字节,要将其处理成字符。所以建立字节转字符的转换字符流
			isr = new InputStreamReader(System.in);
			// 将字符写出到文件中,建立文件输出字符流
			fw = new FileWriter("D:\\content.txt");
			char[] buf = new char[1024];
			int len = 0;
			while ((len = isr.read(buf)) != -1) {
				//去掉回车换行
				String content = new String(buf,0,len-2);
				//当输入end时,停止从键盘上获取字符。
				if("end".equals(content)) {
					break;
				}else{
					fw.write(content);
					//加入回车换行。
					fw.write("\r\n");
					fw.flush();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (isr != null)
					isr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (fw != null)
					fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

为了提高流处理的效率,我们可以为流加上缓冲区。

四个用于缓冲的类:

同样,缓冲字节流的BufferedInputStream,BufferedOutputStream.

同样,缓冲字符流的BufferedReader,BufferedWriter.

通常我们操作流的时候,效率极低,而且IO流提供给我们的缓冲类为什么提供了读取或操作数据很方便的方法。如BufferedReader的readLine()读取一行的方法,newLine()的方法等等。

缓冲流的使用也非常简单,构造缓冲流,接着将要缓冲的流传入即可。

例子如下,为上面的文本文件复制加入缓冲。

package com.java4fun;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class IOTest {
	public static void main(String[] args) {
		copyFile();
	}

	private static void copyFile() {
		BufferedReader br = null;
		BufferedWriter bw = null;
		try {
			// 缓冲流中传入用于读文本,处理文件的字符流
			br = new BufferedReader(new FileReader("D:\\log.txt"));
			// 缓冲流中传入用于写出文本,处理文件的字符流
			bw = new BufferedWriter(new FileWriter("D:\\log_copy.txt"));
			// 将数据读入后存入字符数据中
			String line = null;
			while((line = br.readLine())!=null){
				//写入一行文本数据,这个方法不会写入一行中的换行字符\r\n
				bw.write(line);
				//换行方法
				bw.newLine();
				bw.flush();
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException("未找到要复制的文件");
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("建立复制文件异常");
		} finally {
			try {
				if (br != null)
					//缓冲流的关闭实际是对作用流的关闭
					br.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException("关闭输入流异常");
			}
			try {
				if (bw != null)
					bw.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException("关闭输出流异常");
			}
		}
	}
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值