zoukankan      html  css  js  c++  java
  • 内存映射文件MappedByteBuffer和Buffer的Scattering与Gathering

    上一篇讲到的DirectByteBuffer继承自MappedByteBuffer

    一、MappedByteBuffer

    MappedByteBuffer的定义:

    A direct byte buffer whose content is a memory-mapped region of a file.

    直接缓存,内容是一个内存映射文件。

    创建测试类

    public class NioTest9 {
        public static void main(String[] args) throws  Exception {
            RandomAccessFile randomAccessFile = new RandomAccessFile("NioTest9.txt","rw");
            FileChannel fileChannel =  randomAccessFile.getChannel();
            MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0,5);
            mappedByteBuffer.put(0,(byte)'a');
            mappedByteBuffer.put(3,(byte)'b');
    
            randomAccessFile.close();
        }
    }
    

     创建NioTest9.tex文件

     运行程序,用记事本打开

    操作的是堆外内存,堆外内存写入到文件由操作系统控制。

    二、排他锁和共享锁

    实际用的比较少

    /**
     * 
     * 共享锁: 所有程序都能多共享的部分进行读
     * 排他锁: 只有一个程序对锁定的部分进行写操作
     * 
     */
    public class NioTest10 {
    
        public static void main(String[] args) throws Exception {
            RandomAccessFile randomAccessFile = new RandomAccessFile("NioTest10.txt", "rw");
    
            FileChannel fileChannel = randomAccessFile.getChannel();
    
           FileLock fileLock = fileChannel.lock(3,6,true);
    
            System.out.println("valid:" + fileLock.isValid());
    
            System.out.println("lock type:" + fileLock.isShared());
    
            fileLock.release();
    
            randomAccessFile.close();
        }
    }
    

      

    三、关于Buffer的Scattering(散开)与Gathering(收集)

    /**
     *
     * 关于Buffer的Scattering(散开)与Gathering(收集)
     *
     */
    public class NioTest11 {
    
        public static void main(String[] args) throws Exception {
    
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    
            InetSocketAddress address = new InetSocketAddress(8899);
    
            serverSocketChannel.socket().bind(address);
    
            int messageLength = 2 + 3 + 4;
            ByteBuffer[] buffers = new ByteBuffer[3];
            buffers[0] = ByteBuffer.allocate(2);
            buffers[1] = ByteBuffer.allocate(3);
            buffers[2] = ByteBuffer.allocate(4);
    
            SocketChannel socketChannel = serverSocketChannel.accept();
    
            while (true){
                int byteRead = 0;
                while (byteRead < messageLength){
                    long r = socketChannel.read(buffers);
                    byteRead += r;
    
                    System.out.println("bytesRead:" + byteRead);
    
                    Arrays.asList(buffers).stream().map(buffer -> "position:" + buffer.position() +",limit:" + buffer.limit() + " 值:" + buffer.toString()).forEach(System.out::println);
                }
    
                Arrays.asList(buffers).forEach(buffer -> {
                    buffer.flip();
                });
    
                long byteWritten = 0;
                while (byteWritten < messageLength){
                    long r = socketChannel.write(buffers);
                    byteWritten += r;
                }
    
    
                Arrays.asList(buffers).forEach(bufffer -> {
                    bufffer.clear();
                });
    
                System.out.println("bytesRead:" + byteRead + ",byteWritten: " + byteWritten +", messageLength:" + messageLength);
            }
    
        }
    }
    

      使用Telnet发送,输出结果如下图:

  • 相关阅读:
    分析现有 WPF / Windows Forms 程序能否顺利迁移到 .NET Core 3.0(使用 .NET Core 3.0 Desktop API Analyzer )
    .NET 命令行参数包含应用程序路径吗?
    WPF 多线程 UI:设计一个异步加载 UI 的容器
    .NET/C# 使用反射调用含 ref 或 out 参数的方法
    .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
    .NET/C# 使用反射注册事件
    都是用 DllImport?有没有考虑过自己写一个 extern 方法?
    好的框架需要好的 API 设计 —— API 设计的六个原则
    Netty源码学习(七)FastThreadLocal
    Netty源码学习(六)ChannelPipeline
  • 原文地址:https://www.cnblogs.com/linlf03/p/11354571.html
Copyright © 2011-2022 走看看