一个
字节数组(但没有String;假定我们可用字节数组创建一个);
除此以外,
FilterOutputStream为“破坏器”类提供了一个基础类,它将属性或者有用的接口同输出流连接起来。这将在以后讨论。
ByteArrayOutputStream 在内存中创建一个缓冲区。我们发送给流的所有数据都会置入这个缓冲区。 可选缓冲区的初始大小/用于指出数据的目的地。若将其同
FilterOutputStream对象连接到一起,可提供一个有用的接口
PipedOutputStream 我们写给它的任何信息都会自动成为相关的PipedInputStream的输出。实现了“管道化”的概念 PipedInputStream/为多线程处理指出自己数据的目的地/将其同FilterOutputStream对象连接到一起,便可提供一个有用的接口
FilterOutputStream 对作为破坏器接口使用的类进行抽象处理;那个破坏器为其他OutputStream类提供了有用的功能。参见表10.4
根据写数据的方式不同,OutputStream主要分成两类;一类是写给人看的,一类是供DataInputStream用的。虽然
RandomAccessFile的数据格式同DataInputStream和DataOutputStream的相同,但它不属于OutputStream的。
PrintWriter会对数据进行格式化,这样人就能读懂了。但是如果
数据输出之后,还要恢复出来供其它流用,那你就必须用DataOutputStream来写数据,再用DataInputStream来读数据了。当然,它们可以是任何流,不过我们这里用的是一个经缓冲的文件。DataOutputStream和DataInputStream是面向byte的,因此这些流必须都是InputStream和OutputStream。
如果数据是用DataOutputStream写的,那么不管在哪个平台上,DataInputStream都能准确地把它还原出来。这一点真是太有用了,因为没人知道谁在为平台专属的数据操心。如果你在两个平台上都用Java,那这个问题就根本不存在了 。
用DataOutputStream写String的时候,要想确保将来能用DataInputStream恢复出来,唯一的办法就是使用UTF-8编码,也就是像例程第5部分那样,用writeUTF( )和readUTF( )。UTF-8是
Unicode的一种变形。Unicode用两个字节来表示一个字符。但是,如果你处理的全部,或主要是ASCII
字符(只有7位),那么无论从存储空间还是从带宽上看,就都显得太浪费了,所以
UTF-8 用一个字节表示
ASCII字符,用两或三个字节表示非ASCII的字符。此外,字符串的长度信息存在(字符串)的头两个字节里。writeUTF( )和readUTF( )用的是Java自己的UTF-8版本(
JDK文档里有关于这个
字符集的完整讲解,就在这两个方法的文档里),所以如果你要用一个Java程序读取writeUTF( )写的字符串的话,就必须进行一些特殊处理了。
有了writeUTF( )和readUTF( ),你就能放心地把String和其它数据混在一起交给DataOutputStream了,因为你知道String是以Unicode的形式存储的,而且可以很方便地用DataOutputStream恢复出来。
正如我们前面所讲的,如果不算它实现了DataInput和DataOutput接口,
RandomAccessFileRandomAccessFile的用法就像是DataInputStream和DataOutputStream的结合(因为它们的接口是等效的)。此外,你还能用seek( )在文件里上下移动,并进行修改。