通过零拷贝实现高性能文件传输

x33g5p2x  于2022-05-20 转载在 其他  
字(1.0k)|赞(0)|评价(0)|浏览(236)

一 点睛

对于缓冲区,有操作“直接缓冲区”和操作“非直接缓冲区”两种方式。

1 使用非直接缓冲区进行文件读写

2 使用直接缓冲区进行文件读写

3 注意

a 零拷贝是指用户空间与内核空间之间的复杂次数,并不代表内核空间内部也不存在复制。

b 数据的复制会涉及 I/O 操作,而 I/O 操作是由操作系统完成的,因此零拷贝既减少了数据的复制次数,又降低了 CPU 的负载压力。

二 实战

1 说明

在直接缓冲区,使用内存映射文件,并借助 Channel 完成文件的复制。

2 代码

public static void test3() throws IOException {
    long start = System.currentTimeMillis();
    // 文件的输入通道
    FileChannel inChannel = FileChannel.open(Paths.get("g:\\navicat.chm"), StandardOpenOption.READ);
    // 文件的输出通道
    FileChannel outChannel = FileChannel.open(Paths.get("g:\\navicat_copy3.chm"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
    // 输入通道和输出通道之间的内存映射文件(内存映射文件处于堆外内存中)
    MappedByteBuffer inMappedBuf = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
    MappedByteBuffer outMappedBuf = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());
    // 直接对内存映射文件进行读写
    byte[] dst = new byte[inMappedBuf.limit()];
    inMappedBuf.get(dst);
    outMappedBuf.put(dst);
    inChannel.close();
    outChannel.close();
    long end = System.currentTimeMillis();
    System.out.println("复制操作消耗的时间(毫秒):" + (end - start));
}

3 测试

复制操作消耗的时间(毫秒):30

相关文章