新I/O
JDK1.4的Java.nio.*包中引入了新的JavaI/O类库,其目的在于提高速度。而速度的提高来自于所使用的结构更接近于操作系统执行I/O的方式:通道和缓冲器。
我们可以把它想象成一个煤矿,通道是一个包含煤层(数据)的矿藏,而缓冲器则是派送到矿藏的卡车。卡车载满煤炭而归,我们再从卡车上获得煤炭。也就是说,我们并没有直接和通道交互,我们只是和缓冲器交互,并把缓冲器派送回通道。通道要么从缓冲器获取数据,要么向缓冲器发送数据。
唯一直接与通道交互的缓冲器是ByteBuffer——也就是说,可以存储未加工字节的缓冲器。它是相当基础的类:通过告知分配多少存储空间来创建一个ByteBuffer对象,并且还有一个方法选择集,用于以原始的字节形式或基本数据类型输出和读取数据。但是,没办法输出或读取对象,包括字符串对象。这种处理虽然很低级,却也正好。因为这是大多数操作系统中更有效的映射方式。
旧I/O类库中有三个类被修改了,用以产生FileChannel。这三个被修改的类是FileInputStream、FileOutputStream以及用于既读又写的RandomAccessFile。
1. 通道是一种相当基础的东西:可以向它传送用于读写的ByteBuffer,并且可以锁定文件的某些区域用于独占式访问。
2. 将字节存放于ByteBuffer的方法之一是用put直接填充。也可以使用wrap()方法将已存在的字节数据包装到ByteBuffer中。一旦如此,就不能复制底层的数组,而是将它作为所产生的ByteBuffer的存储器(没太理解这句话?)。
3. 一旦调用read()来告知FileChannel向ByteBuffer存储字节,就必须调用缓冲器上的flip(),让它做好让别人读取字节的准备(这似乎有一点拙劣,但是却适用于获取最大速度)。如果我们打算使用缓冲器执行进一步的read操作,我们也必须调用clear()来为每个read()做好准备。
脑洞:read() Returns the number of bytes read, possibly zero, or -1 if
the channel has reached end-of-stream是以int形式返回下一字节,所以while (in.read(buffer)!= -1) {…}
readline() Returns a String containing the contents of the line, not
including any line-termination characters, or null if the end of the stream
has been reached 返回的是字符串, 所以while ((s = br.readLine())!= null) {…}
|
4. clear()操作是对所有的内部指针重新安排,以便缓冲器在另一个read()操作期间能够做好接收数据的准备。
5. 特殊方法transferTo()和transferFrom()则允许我们将一个通道和另一个通道直接相连。
No comments:
Post a Comment