Java中的NIO详解Day07-FileChannel

FileChannel

  • 基本概念
  • 开启FileChannel
  • 从FileChannel中读取数据
  • 向FileChannel中写数据
  • 关闭FileChannel
  • FileChannel中的方法
      • position()
      • size()
      • truncate()
      • force()

基本概念

  • Java NIO中的FileChannel是一个连接到文件的通道,可以通过文件通道读写文件
  • FileChannel无法设置为非阻塞模式,总是运行在阻塞模式下

开启FileChannel

  • 在使用FileChannel之前,必须先打开FileChannel
  • FileChannel无法直接打开,需要通过使用一个InputStream,OutputStream或者RandomAccessFile来获取一个FileChannel实例
  • 示例: 通过RandomAccessFile打开FileChannel
RandomAccessFile file = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel fileChannel = file.getChannel();

从FileChannel中读取数据

  • 通过调用read() 方法从FileChannel中读取数据:
ByteBuffer buffer = ByteBuffer.allocate(64);
int bytesRead = fileChannel.read(buffer);
  • 首先,分配一个Buffer.FileChannel中读取的数据将被读取到Buffer
  • 然后,调用FileChannel.read() 方法,该方法将数据从FileChannel读取到Buffer.read() 方法返回的int值表示有多少字节被读取到了Buffer中,如果返回 -1, 表示到达了文件末尾

向FileChannel中写数据

  • 使用FileChannel.write() 方法向FileChannel中写数据,该方法的参数是一个Buffer:
ByteBuffer buffer = ByteBuffer.allocate(64);
buffer.clear();
buffer.put(dataString);
buffer.flip();
while (buffer.hasRemaining()) {
	fileChannel.write(buffer);
}
  • FileChannel.write() 是在while中循环调用的
  • 因为无法保证write() 方法一次能向FileChannel中写入多少字节,因此需要重复调用write() 方法,直到Buffer中已经完全没有尚未写入的字节

关闭FileChannel

  • 使用完毕的FileChannel必须要进行关闭:
fileChannel.close()

FileChannel中的方法

position()

  • 如果需要在FileChannel的某个特定位置进行数据的读写操作
  • 可以通过调用position() 方法获取FileChannel的当前位置
  • 也可以通过调用position(long pos) 方法设置FileChannel的当前位置
long pos = channel.position();
channel.position(pos + 128);
  • 如果将位置设置在文件结束符之后,然后再从文件通道中读取数据 ,FileChannel的读方法将返回文件结束标志 -1
  • 如果将位置设置在文件结束符之后,然后向通道中写数据.文件将扩充到当前位置并写入数据,这可能会导致 “文件空洞” 问题,即磁盘上物理文件中写入的数据间有空隙

size()

  • 通过调用FileChannel实例的size() 方法将会返回该实例所关联的文件的大小
long fileSize = fileChannel.size();

truncate()

  • 可以使用FileChannel.truncate() 方法截取一个文件
    • 截取文件时,文件中指定长度后面的部分将会被删除
/*
 * 截取文件的前1024个字节
 */
fileChannel.truncate(1024);

force()

  • 使用FileChannel.force() 方法可以将通道里尚未写入磁盘的数据强制写到磁盘上
  • 因为出于性能方面的考虑,操作系统会首先将数据缓存在内存中,所以无法保证写入到FileChannel里的数据一定会即时写到磁盘上
  • 可以通过调用force() 方法保证写入到FileChannel里的数据一定会即时写到磁盘上
  • force()方法中有一个boolean参数: 指明是否同时将文件的权限信息等元数据写到磁盘上
  • 示例: 同时将文件数据和元数据强制写到磁盘上
fileChannel.force(true);

你可能感兴趣的:(架构)