MappedByteBuffer

  • Post author:
  • Post category:其他


MappedByteBuffer是ByteBuffer的子类,和ByteBuffer的使用方式类似,一般用于加速文件和内存之间的IO传输的速度,原理可理解为是给磁盘文件和app应用内存之间建立了一条快速通道,而这条快速通道就是MappedByteBuffer,通过对它的读或写就相当于对文件的读或写,不需要再经过用户态和内核态的数据来回拷贝。下面示例通过socket的传输,把client的传输的结果写到磁盘mmap.txt中

Server

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8080));

        int lastPosition = 0;

        File file = new File("D:\\mmap.txt");
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
        FileChannel fileChannel = randomAccessFile.getChannel();
        //开启mmap,把文件映射到内存,对mappedByteBuffer操作即可操作文件
        MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);

        while (true){
            SocketChannel socketChannel = null;
            try {
                socketChannel = serverSocketChannel.accept();
                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                int len = socketChannel.read(byteBuffer);
                if (len < 0){
                    continue;
                }
                byteBuffer.flip();
                //position指针移动到上次最后一次写入的地方
                mappedByteBuffer.position(lastPosition);
                //把client读取数据写入到mappedByteBuffer
                mappedByteBuffer.put(byteBuffer);
                //记录当前position
                lastPosition = mappedByteBuffer.position();
                //强行刷到磁盘
                mappedByteBuffer.force();

                //读出所有mappedByteBuffer的数据
                mappedByteBuffer.flip();
                byte[] dst = new byte[mappedByteBuffer.remaining()];
                mappedByteBuffer.get(dst, 0, mappedByteBuffer.remaining());
                System.out.println(new String(dst));

                byteBuffer.clear();
                mappedByteBuffer.clear();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                socketChannel.close();
            }
        }
    }
}

Client

public class Client {
    public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(8080));
        socketChannel.write(ByteBuffer.wrap("abcde".getBytes(StandardCharsets.UTF_8)));
        socketChannel.close();
    }
}

输出结果

先启动server,再执行client(3次)

abcde
abcdeabcde
abcdeabcdeabcde



版权声明:本文为u013733399原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。