IO流中有两个主要的体系:字节流与字符流
字节流包括字节输入流(InputStream)与字节输出流(OutputStream)。
字符流包括字符输入流(Reader)与字符输出流(Writer)。
字节流与字符流的用法几乎一致,区别在于二者所操作(读/写)的数据不同,字节流操作的是8位的字节,字符流则是16位的字符。
字节流的功能更为强大,可以处理任意的二进制文件(包括字符文件),但处理字符文件还需要字节到字符的转换,故若是字符文件应当使用字符流处理。
计算机文件常被分为文本文件与二进制文件两大类,文本文件是由字符构成的文件,除文本文件外其他都是二进制文件。
如下示例,文件Data.txt是文本文件,既可以使用字节流操作也可以使用字符流操作。
// 文件Data.txt的字节输入流 FileInputStream fis = new FileInputStream("Data.txt"); byte[] b = new byte[10]; // 按字节读取Data.txt中的内容于字节数组b中 fis.read(b); // 文件Data.txt的字符输入流 FileReader fr = new FileReader("Data.txt"); char[] c = new char[10]; // 按字符读取Data.txt中的内容于字符数组c中 fr.read(c);
IO流又可以分为节点流与处理流
节点流 可以向一个特定的IO设备(磁盘、网络)读写数据的流,为节点流。
处理流 包装节点流的流为处理流
节点流直接与一个IO设备(如某个文件)建立关联,处理流通过包装节点流建立更高级的流。
处理流屏蔽了底层设备并提供更加方便的输入输出方法,通用性更强。处理流不用频繁的与IO设备操作(如Buffered流),效率更高。
示例:
public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("test.txt"); PrintStream ps = new PrintStream(fos);
// 向文件test.txt中输出字符 ps.print("Hello World "); ps.print("A nice day"); }
fos为节点流,对应文件test.txt。
ps为处理流,包装节点流fos。
InputStream/Reader 所有输入流的基类,前者是字节输入流,后者是字符输入流
OutputStream/Writer 所有输出流的基类
输入输出流常用类如下:
如何确定使用哪个类?
第一步,首先,明确IO流中有两个主要的体系,即字节输入流(InputStream)、字节输出流(OutputStream)和字符输入流(Reader)、字符输出流(Writer)。其次,明确数据的来源和数据将要到达的目的地。
第二步,明确将要操作的数据是否是纯文本数据。如果数据源是纯文本数据选Reader;数据源不是纯文本数据选择InputStream。如果数据目的地是纯文本数据就选择Writer;如果不是则选择OutputStream。
第三步,明确具体的设备。即数据源是从哪个设备来的:是硬盘就加File;是键盘用System.in(是一个InputStream对象);是内存用数组;是网络用Socket流。同样目的是哪个设备:是硬盘就加File;是键盘用System.out(是一个OutoutStream对象);是内存用数组;是网络用Socket流。
第四步,明确是否还需要其他额外功能呢,例如①是否需要较高的效率,即是否需要使用缓冲区,是就加上Buffered;②是否需要转换,是,就使用转换流,InputStreamReader 和OutputStreamWriter。