java nio

作者: 追风还是少年 | 来源:发表于2023-09-08 00:06 被阅读0次

    ByteBuffer

    Buffer属性:

    • capacity
      buffer容量,设置之后就不会改变
    • limit
      第一个不能读或不能写的位置,即读写的终点位置
    • position
      读到buffer的哪个位置或写到buffer的哪个位置
    • mark
      标记当前位置,当调用reset方法后可以恢复position为之前标记的位置

    以上属性的大小关系:
    0 <= mark <= position <= limit <= capacity

    Buffer操作:

    • clear()
      清除position、limit、mark恢复为初始化默认值
      设置limit = capacity、position = 0、mark=-1
    • flip()
      切换读写模式,如果mark属性设置过,会丢弃之前的值
      设置limit = position、position = 0、mark=-1
    • rewind()
      重新开始读,重置mark属性值为-1
      limit不变,设置postion = 0、mark = -1
    • slice()
      创建新的Buffer,原来Buffer的limit和position保持不变
      -duplicate()
      创建Buffer的浅拷贝,原来Buffer的limit和position保持不变
    • mark()
      记录下当前位置到mark属性,设置 mark = position
    • reset()
      重置position属性为之前标记的位置,设置 posion = mark
    • remaining()
      返回Bufer剩余可读的元素个数或剩余可写的元素个数,即limit-position
    • hasRemaining()
      返回是否有剩余数据可读或剩余空间可写, 即limit<position
    import java.nio.ByteBuffer;
    
    public class ByteBufferTest {
        public static void main(String[] args) {
            // HeapByteBuffer
            ByteBuffer byteBuffer = ByteBuffer.allocate(6);
           // DirectByteBuffer
           // ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6);
            // 1、初始化容量为6的ByteBuffer
            print("1、初始化容量为6的ByteBuffer", byteBuffer);
    
    
            byteBuffer.putInt(1);
            //2、写入4个字节数据后
            print("2、写入4个字节数据后", byteBuffer);
    
            byteBuffer.flip();
            //3、调用flip()方法切换为读模式后
            print("3、调用flip()方法切换为读模式后", byteBuffer);
    
            byteBuffer.get();
            //4、读取一个字节数据后
            print("4、读取一个字节数据后", byteBuffer);
    
            int remainding = byteBuffer.remaining();
            //5、调用remaining()方法获取剩余未读或未写字节数
            System.out.println("5、调用remaining()方法获取剩余未读或未写字节数: " + remainding);
    
            byteBuffer.clear();
            //6、再次调用flip()方法切换为写模式后
            print("6、调用clear()方法", byteBuffer);
    
        }
    
        public static void print(String title,ByteBuffer byteBuffer){
            System.out.print(title + ": position = " + byteBuffer.position());
            System.out.print(", ");
            System.out.print("limit = " + byteBuffer.limit());
            System.out.print(", ");
            System.out.print("capacity = " + byteBuffer.capacity());
            System.out.println();
        }
    }
    

    日志输出

    1、初始化容量为6的ByteBuffer: position = 0, limit = 6, capacity = 6
    2、写入4个字节数据后: position = 4, limit = 6, capacity = 6
    3、调用flip()方法切换为读模式后: position = 0, limit = 4, capacity = 6
    4、读取一个字节数据后: position = 1, limit = 4, capacity = 6
    5、调用remaining()方法获取剩余未读或未写字节数: 3
    6、调用clear()方法: position = 0, limit = 6, capacity = 6
    
    image.png image.png image.png

    FileChannel

    FileInputStream/FileOutputStream与FileChannel对比:

    • 流的方向
      FileInputStream/FileOutputStream是单向的
      FileChannel是双向的
    • 面向字节还是面向Buffer
      FileInputStream/FileOutputStream面向字节的读写
      FileChannel面向Buffer读写
    • 支持特性
      FileChannel支持内存文件映射、转入或转出其他通道、支持文件锁
      FileInputStream/FileOutputStream都不支持以上的特性

    方法:

    • open()
      创建FileChannel
    • read/write()
      基于FileChannel读写
    • force()
      强制将FileChannel中的数据刷入文件中
    • map()
      内存文件映射
    • transferTo/transferFrom()
      转入与转出通道
    • lock/tryLock()
      获取文件锁

    创建FileChannel方式:

    • open
      用于创建一个FileChannel对象。具有两种重载形式
    public static FileChannel open(Path path, OpenOption... options) throws IOException
    
    public static FileChannel open(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
    

    OpenOption主要用于控制文件的操作模式:
    (1) READ:只读方式
    (2) WRITE:只写方式
    (3)APPEND:只追加方式
    (4)CREATE:创建新文件
    (5)CREATE_NEW:创建新文件,如果存在则失败
    (6)TRUNCATE_EXISTING:如果以读方式访问文件,它的长度将被清除至0

    Path path = FileSystems.getDefault().getPath("D:/test.txt");
    FileChannel channel2 = FileChannel.open(path, StandardOpenOption.READ);
    
    • 通过FileInputStream/FileOutputStream提供的getChannel
    FileInputStream inputStream = new FileInputStream("D:/test.txt");
    FileChannel channel = inputStream.getChannel();
    
    FileOutputStream outputStream = new FileOutputStream("D:/test.txt");
    FileChannel channel1 = outputStream.getChannel();
    
    • 通过RandomAccessFile的getChannel
    this.fileChannel = new RandomAccessFile(this.file, "rw").getChannel();
    this.mappedByteBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, fileSize);
    

    相关文章

      网友评论

          本文标题:java nio

          本文链接:https://www.haomeiwen.com/subject/ridrvdtx.html