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);
还没有评论,来说两句吧...