NIO之Buffer操作示例

1. buffer常规操作 略

2. 只读buffer

/**
 * 只读buffer
 */
public class BufferTest01 {
    public static void main(String[] args) {
        IntBuffer buffer = IntBuffer.allocate(10);

        for (int i = 0; i < 10; i++) {
            buffer.put(i);
        }

        buffer.flip();
        // 这个buffer1只能读
        IntBuffer buffer1 = buffer.asReadOnlyBuffer();

        for (int i = 0; i < 10; i++) {
            System.out.println(buffer.get());
        }

        // 如果再往buffer1中put数据,则会报错ReadOnlyBufferException
        buffer1.put(10);

    }
}

3. 映射buffer

/**
 * MappedByteBuffer 可以让文件直接在堆外内存中修改,这样操作系统不需要拷贝一次
 */
public class MappedByteBufferTest02 {
    public static void main(String[] args) throws Exception {
        RandomAccessFile file = new RandomAccessFile("1.txt", "rw");
        // 获取对应的文件通道
        FileChannel channel = file.getChannel();
        /*
         *FileChannel.MapMode.READ_WRITE: 表示是读写模式
         * 0 : 可以修改的起始位置
         * 5 : 我映射到内存的大小(不是索引), 即可以将文件1.txt的5个字节映射到内存, 你映射多少个字节 ,就可以修改多少个字节,
         */
        MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
        mappedByteBuffer.put(0, (byte) 'A');// 将第一个位置改成A
        mappedByteBuffer.put(4, (byte) 'B'); //将第五个位置改成B

        file.close();

    }
}

4. 分散与聚合 

/**
 * scattering : 将数据写入到buffer时,可以采用buffer数组 ,依次写入
 * gathering : 从buffer读取数据时,可以采用buffer数组 ,依次读
 */
public class ScatteringAndGatheringTest {
    public static void main(String[] args) throws Exception {

        // 使用ServerSocketChannel和SocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        InetSocketAddress socketAddress = new InetSocketAddress(8888);
        // 绑定端口到socket上,并启动socket服务
        serverSocketChannel.socket().bind(socketAddress);

        ByteBuffer[] buffers = new ByteBuffer[2];
        buffers[0] = ByteBuffer.allocate(5);
        buffers[1] = ByteBuffer.allocate(3);
        int total = 8;
        // 等待客户端的连接
        System.out.println("等待连接。。。。。");
        SocketChannel socketChannel = serverSocketChannel.accept();

        // 循环读取数据
        while (true) {
            int byteRead = 0;
            while (byteRead < 8) {
                long read = socketChannel.read(buffers);
                byteRead += read;
                System.out.println("已读取:" + byteRead);
                // 流打印, 看看当前buffer的position和limit
                Arrays.asList(buffers).stream().map(x -> "position=" + x.position() + ", limit = " + x.limit()).forEach(System.out::println);
            }

            // 切换
            Arrays.asList(buffers).forEach(x -> x.flip());
            // 将读取出来的数据显示到客户端
            long byteWrite = 0;
            while (byteRead < total) {
                long l = socketChannel.write(buffers);
                byteWrite += l;
            }

            // 复位操作

            Arrays.asList(buffers).stream().map(x -> x.clear());

            System.out.println("byteRead = " + byteRead + ", byteWrite = " + byteWrite + ", total =" + total);


        }
    }
}
原文地址:https://www.cnblogs.com/z-qinfeng/p/11963002.html