在直接缓冲区,使用 MappedByBuffer 修改文件内容。
public static void test4() throws IOException {
RandomAccessFile raf = new RandomAccessFile("G:\\abc.txt", "rw");
FileChannel fileChannel = raf.getChannel();
// mappedByteBuffer:代表了 abc.txt 在内存中的映射文件
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, raf.length());
// 修改内存中的数据
mappedByteBuffer.put(1, (byte) 'X');
// 只需关心内存中的数据
mappedByteBuffer.put(3, (byte) 'Y');
raf.close();
}
a 修改前文件内容
helloworld
b 修改后文件内容
hXlYoworld
如果使用的是直接缓冲区,那么 JVM 在每次调用 I/O 操作之前或之后,都会尽量避免将缓冲区的内容复制到中间缓冲区(或从中间缓冲区中复制内容)。并且直接缓冲区是驻留在 JVM 之外的区域,因此无法受 Java 代码及 GC 的控制。此外,分配直接缓冲区时系统开销较大,因此,建议将直接缓冲区分配给那些持久的、经常重用的数据使用。
使用零拷贝内存的方式,完成文件的复制
// 在直接缓冲区中,将输入通道的数据直接转发给输出通道
public static void test4() throws IOException {
long start = System.currentTimeMillis();
FileChannel inChannel = FileChannel.open(Paths.get("g:\\navicat.chm"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("g:\\navicat1.chm"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
inChannel.transferTo(0, inChannel.size(), outChannel);
/*
也可以使用输出通道完成复制,即上条语句等价于以下写法:
outChannel.transferFrom(inChannel, 0, inChannel.size());
*/
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("复制操作消耗的时间(毫秒):" + (end - start));
}
复制操作消耗的时间(毫秒):7
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/124893923
内容来源于网络,如有侵权,请联系作者删除!