You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FreeBSD下可替代Linux sendfile()/splice()的无缓冲区文件复制方案?

FreeBSD 下无用户态缓冲区的文件描述符间复制方案

FreeBSD 没有和 Linux splice() 完全对等的系统调用,但有两种可靠的零拷贝(无需用户态中间缓冲区)实现方式:

  • copy_file_range():这是POSIX标准化的系统调用,FreeBSD 13.0及以上版本已原生支持。它直接在内核态完成两个文件描述符之间的数据复制,全程不经过用户态内存,支持普通文件间的全量复制或指定偏移、长度的部分复制,典型用法如下:

    off_t src_offset = 0, dst_offset = 0;
    const size_t copy_len = 4096; // 按需调整
    ssize_t copied = copy_file_range(src_fd, &src_offset, dst_fd, &dst_offset, copy_len, 0);
    
  • 旧版本兼容方案(FreeBSD <13.0):如果使用的是13.0之前的版本,没有copy_file_range(),可以通过mmap()将源文件映射到进程地址空间,再用write()写入目标文件——这种方式虽然会涉及内存映射,但内核可以优化为直接从文件缓存写入目标文件,避免用户态缓冲区的实际拷贝。不过这种方式的效率略低于copy_file_range(),示例代码:

    char *src_map = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, src_fd, 0);
    if (src_map != MAP_FAILED) {
        write(dst_fd, src_map, file_size);
        munmap(src_map, file_size);
    }
    

需要注意的是,FreeBSD原生的sendfile()仅支持从文件描述符到套接字的传输,确实无法满足普通文件间的复制需求,因此优先选择copy_file_range()作为替代方案。

内容的提问来源于stack exchange,提问作者000exploit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:17:08