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