首页 > 代码库 > Java IO
Java IO
Reference
[1] http://www.cnblogs.com/youxia/p/java007.html
Byte stream and Character stream
在 Java 中如果要把流中的数据按字节来访问,就应该使用 InputStream 和 OutputStream,如果要把流中的数据按字符来访问,就应该使用 Reader 和 Writer。用来输入的两个类 InputStream 和 Reader 主要定义了read()方法,而用来输出的两个类 OutputStream 和 Writer 主要定义了write()方法。所不同者,前者操作的是字节,后者操作的是字符。很显然,一次处理一个字节效率是及其低下的,所以read()和write()还有别的重载版本:
int read(byte[] b)
int read(byte[] b, int off, int len)
void write(byte[] b)
void write(byte[] b, int off, int len)
int read()
int read(char[] cbuf)
int read(char[] cbuf, int off, int len)
void write(int c)
void write(char[] cbuf)
void write(char[] cbuf, int off, int len)
void write(String str)
void write(String str, int off, int len)
字节流和字符流并不是完全对立的存在,其实字符流是在字节流上更高层次的封装。在底层,一切数据都是字节,但是经过适当的封装,可以把这些字节解释成字符。而且,并不是所有的 Reader 都是可以像 FileReader 那样直接创建的,有时,只能拿到一个可以读取字节数据的 InputStream,却需要在它之上封装出一个 Reader,以方便按字符的方式读取数据。
URL cnblogs = new URL("http://www.cnblogs.com/");
InputStream in = cnblogs.openStream();
Reader reader = new InputStreamReader(in);
所以, InputStreamReader 是沟通字节流和字符流的桥梁。同样的桥梁还用用于输出的 OutputStreamWriter
InputStream、OutputStream、Reader 和 Writer 是抽象的,根据不同的数据来源和目的又有不同的具体类。结合平时使用计算机的经验,我们也可以想到其它一些不同的数据来源和目的,比如从内存中读取字节或把字节写入内存,从字符串中读取字符或者把字符写入字符串等等,还有从管道中读取数据和向管道中写入数据等等。根据不同的数据来源和目的,可以有这样一些具体类:FileInputStream、ByteArrayInputStream、PipedInputStream、FileOutputStream、ByteArrayOutputStream、PipedOutputStream、FileReader、StringReader、CharArrayReader、PipedReader、FileWriter、StringWriter、CharArrayWriter、PipedWriter等。从这些类的命名可以看出,凡是以Stream结尾的,都是操作字节的流,凡是以 Reader 和 Writer 结尾的,都是操作字符的流。只有 InputStreamReader 和 OutputStreamWriter 是例外,它是沟通字节和字符的桥梁。
Various APIs
向流中写入对象和读取对象,操作的肯定是字节流而不是字符流,所以只有 ObjectInputStream 和 ObjectOutputStream,而没有相应的 Reader 和 Writer 版本。再例如打印,操作的肯定是输出流,所以只有 PrintStream 和 PrintWriter,没有相应的输入流版本。
在这些类中,可以通过 PrintStream 和 PrintWriter 向流中写入格式化的文本,也可以通过 DataInputStream 和 DataOutputStream 从流中读取或向流中写入原始的数据,还可以通过 ObjectInputStream 和 ObjectOutputStream 从流中读取或写入一个完整的对象。如果要从流中读取格式化的文本,就必须使用 java.util.Scanner 类了。
使用 DataInputStream 和 DataOutputStream 只能写入和读取原始的数据类型的数据,如byte、char、short、float等,如果要读取和写入复杂的对象就不行了,比如java.math.BigDecimal。这个时候就需要使用 ObjectInputStream 和 ObjectOutputStream 了。所有需要写入流和从流读取的 Object 必须实现Serializable接口,然后调用 ObjectInputStream 和 ObjectOutputStream 的writeObject()方法和readObject()方法就可以了
与以二进制格式写入和读取数据相对的,就是以文本的方式写入和读取数据。PrintStream 和 PrintWriter 中的 Print 就是代表着输出能供人读取的数据。比如浮点数3.14可以输出为字符串"3.14"。利用 PrintStream 和 PrintWriter 中提供的大量print()方法和println()方法就可以做到这点,利用format()方法还可以进行更加复杂的格式化。对于 PrintStream 和 PrintWriter,我们用得最多的就是基于命令行的标准输入输出,也就是从键盘读入数据和向屏幕写入数据。
Java IO