1.对java.nio包的理解
java.nio.*包中引入了新的JavaI/O类库 为了提高IO读写速度。用缓存和通道更加接近操作系统的IO方式
我们要读取到数据,并没有直接和通道交互;只是和缓冲器交互,并把缓冲器派送到通道。通道要么从缓冲器获得数据,要么向缓冲器发送数据!
用户数据读写<-->ByteBuffer<--->FileChannel
2.缓冲区
特定基本类型元素的线性有限序列。除内容外,缓冲区的基本属性还包括容量、限制和位置
读写数据时候 本质就是从此缓冲区的“位置”处一直读到“限制”处!
3. FileChannel的read(ByteBuffer bf):将字节序列从FileChannel读入给定的缓冲区ByteBuffer bf 中!读完以后,bf的当前位置就是从FileChannel中读取的字节个数!
同理,我们应该可以很容易想象出write(ByteBuffer bf)它就是用来将字节序列从给定的缓冲区ByteBuffer bf写入通道FileChannel
3. ByteBuffer 和通道交换作用
通过告知分配多少存储空间来创建一个ByteBuffer对象
ByteBuffer的flip():反转此缓冲区,将限制设置为当前位置,然后将位置设置为 0 !(本质就是设置buff开始位置和结束位置 以便后面可以读写buff)
4.代码实现
FileChannel fc = new FileOutputStream("s.txt").getChannel(); fc.write(ByteBuffer.wrap("Some text".getBytes()));//将 byte 数组包装到缓冲区中buff中去,然后写到fc中去 fc.close(); fc = new RandomAccessFile("s.txt", "rw").getChannel(); fc.position(fc.size());//到最后位置然后 后面的byte加到后面 fc.write(ByteBuffer.wrap("Some more".getBytes())); fc.close(); fc = new FileInputStream("s.txt").getChannel(); ByteBuffer buff = ByteBuffer.allocate(BSIZE); fc.read(buff); buff.flip(); while (buff.hasRemaining()) {// 是否到达限定的位置 System.out.println((char) buff.get()); }
总结如下:
1. put 数据时, 不会自动清除缓冲区中现有的数据.
2. 每一次 get 或 put 后, curPointer 都将向缓冲区尾部移动, 移动量=操作的数据量.
3. get/put 均是从 curPointer 起, 到 curPointer + 操作的数据长度止.
4. get/put 操作中, 若 curPointer 超过了 endPointer 或缓冲区总长度, 将抛出 java.nio.BufferUnderflowException 异常.