c++ - sendfile64 只复制大约 2GB

标签 c++ c linux sendfile

我需要使用 sendfile64 来复制大约 16GB 的文件。到目前为止我取得的成就是

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/sendfile.h>
#include <sys/stat.h>

int main (int argc, char** argv)
{
  long long src;
  long long dest;
  struct stat64 stat_buf;
  off64_t offset = 0LL;
  long long rc;

  if (argc != 3) {
    fprintf(stderr, "usage: %s <source> <destination>\n", argv[0]);
    exit(1);
  }

  src = open64(argv[1], O_RDONLY);
  if (src == -1) {
    fprintf(stderr, "unable to open '%s': %s\n", argv[1], strerror(errno));
    exit(1);
  }

  fstat64(src, &stat_buf);

  dest = open64(argv[2], O_WRONLY|O_CREAT, stat_buf.st_mode);
  if (dest == -1) {
    fprintf(stderr, "unable to open '%s': %s\n", argv[2], strerror(errno));
    exit(1);
  }

 /* copy file using sendfile */
 rc = sendfile64 (dest, src, &offset, stat_buf.st_size);
 if (rc == -1) {
    fprintf(stderr, "error from sendfile: %s\n", strerror(errno));
    exit(1);
 }
 if (rc != stat_buf.st_size) {
   fprintf(stderr, "incomplete transfer from sendfile: %lld of %lld bytes\n",
           rc,
           (long long)stat_buf.st_size);
   exit(1);
 }

 /* clean up and exit */
 close(dest);
 close(src);

 return 0;
}

我编译使用

g++ BigCopy2.cpp -o BigCopy2 -D_FILE_OFFSET_BITS=64 -DLARGEFILE64_SOURCE

问题是我仍然无法复制超过 2GB 的文件。

谁能指出我的错误在哪里?

最佳答案

您应该使用循环来复制所有数据,sendfile() 可能由于各种原因不会复制所有数据 一个电话。正如 janneb 指出的那样,sendfile64 的返回值是一个 ssize_t,因此我们不应将超过 SSIZE_MAX 的值传递给 sendfile,而且 sendfile 的最后一个参数是一个 size_t,在 32 位平台上将是 32 位。

 /* copy file using sendfile */
while (offset < stat_buf.st_size) {
  size_t count;
  off64_t remaining = stat_buf.st_size- offset;
  if (remaining > SSIZE_MAX)
      count = SSIZE_MAX;
   else 
      count = remaining;
  rc = sendfile64 (dest, src, &offset, count);
  if (rc == 0) {
     break;
  }
  if (rc == -1) {
     fprintf(stderr, "error from sendfile: %s\n", strerror(errno));
     exit(1);
  }
}

 if (offset != stat_buf.st_size) {
   fprintf(stderr, "incomplete transfer from sendfile: %lld of %lld bytes\n",
           rc,
           (long long)stat_buf.st_size);
   exit(1);
 }

请注意,您可以将所有 64 位变体 off64_t、stat64、sendfile64 替换为 off_t、stat、sendfile。只要你有 -D_FILE_OFFSET_BITS=64 标志,如果这些类型和函数还不是 64 位(例如与 32 位架构一样)。

关于c++ - sendfile64 只复制大约 2GB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22373528/

相关文章:

c - 释放 C 中动态内存的第一部分

linux - Unix 和 Linux 文件并发读/写处理

c++ - 复合模式 : Copy tree structure

c++ - 为什么不能在 C++ 中重载所有内容?

c - 如何使用 Lua 中的函数指针和 SWIG 绑定(bind)来调用函数?

c - 如何在终端中输入/输入特殊字符 ETB(ASCII 23) 作为字符?

php 在 Linux 上太慢?

C++ 'vector' 未在此范围内声明

c++ - 为什么成员函数指针的类型基于实际声明该函数的类?

用 C 计算 3D FFT 和逆 FFT