通道映射
- 通道映射是一种快速读写技术,将通道所连接的数据节点中的全部或者部分数据映
射到内存的一个Buffer中,而这个内存Buffer块就是节点数据的映像,直接对这个
Buffer块进行修改会直接影响到节点数据,另外,这个Buffer也不是普通的Buffer,叫
做MappedBuffer,即镜像Buffer。
- map原型:MappedByteBuffer map(MapMode mode, long position, long size);
作用是:将节点中从position开始的size字节映射到返回的MapppedByteBuffer中
- MapMode具有三种映射模式,且都是Channel的内部类MapMode定义的静态常量
此处以FileChannel举例:
(1)FileChannel.MapMode.READ_ONLY:得到的镜像只能写
(2)FileChannel.MapMode.READ_WRITE:得到的镜像可读可写,对其写会直接
会直接更新到存储节点
(3)FileChannel.MapMode.PRIVATE:得到一个私有镜像,其实就是一个
(position, size)区域的副本,也是可读可写,只不过写不会影响到存储节点,即
普通的ByteBuffer
- 映射的规则
(1)使用InputStream获得的Channel可以映射,但是map只能指定为READ_ONLY
(2)使用OutputStream得到的Channel不可以映射
(3)使用RandomAccessFile获取的Channel可以任意开启这三种模式
- MappedByteBuffer的用法和普通的ByteBuffer一样,只不过它的功能被上述的规则限制了,比如只读的就只能get,不能put,可写的以及私有的put,get都能用
- 只读映射
public class Test {
public static void main(String[] args) throws IOException {
File file = new File("...");
try {
FileChannel fileChannel = new FileInputStream(file).getChannel();
MappedByteBuffer mappedByteBuffer =
fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
Charset charset = Charset.forName("GBK");
System.out.println(charset.decode(mappedByteBuffer)); // "hello world"
// 将limit属性设置为当前的位置,回到缓冲区的第一个位置
mappedByteBuffer.flip();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
- RandomAccessFile的通道映射可读可写
(1)RandomAccessFile获取的通道同样是FileChannel,在读写模式下,对内存镜像的修改会直接更新到节点文件。(long position()用于获取当前操作到节点文件的具体位置)