当前位置: 首页 > 知识库问答 >
问题:

sendfile64仅拷贝2GB左右

竺焕
2023-03-14

我需要使用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的文件

有人能告诉我哪里错了吗?

共有1个答案

方浩旷
2023-03-14

您应该使用循环来复制所有数据,因为各种原因,sendfile()可能不会一次调用就复制所有数据。正如janneb指出的那样,sendfile64的返回值是一个ssize_t,因此我们不应该向sendfile传递超过ssize_MAX的值,而且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位体系结构上),那么define将做正确的事情,并将off_t转换为off64_t,将sendfile转换为sendfile64等等。

 类似资料:
  • 主要内容:到底是浅拷贝还是深拷贝对于基本类型的数据以及简单的对象,它们之间的拷贝非常简单,就是按位复制内存。例如: b 和 obj2 都是以拷贝的方式初始化的,具体来说,就是将 a 和 obj1 所在内存中的数据按照二进制位(Bit)复制到 b 和 obj2 所在的内存, 这种默认的拷贝行为就是 浅拷贝 ,这和调用 memcpy() 函数的效果非常类似。 对于简单的类,默认的拷贝构造函数一般就够用了,我们也没有必要再显式地定义一

  • 浅拷贝 对于对象或数组类型,当我们将a赋值给b,然后更改b中的属性,a也会随着变化。 也就是说,a和b指向了同一块堆内存,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝。 深拷贝 那么相应的,如果给b放到新的内存中,将a的各个属性都复制到新内存里,就是深拷贝。 也就是说,当b中的属性有变化的时候,a内的属性不会发生变化。 参考链接: 深拷贝与浅拷贝的实现(一) javaScript中浅拷

  • 一、引言 对象拷贝(Object Copy)就是将一个对象的属性拷贝到另一个有着相同类类型的对象中去。在程序中拷贝对象是很常见的,主要是为了在新的上下文环境中复用对象的部分或全部数据。Java中有三种类型的对象拷贝:浅拷贝(Shallow Copy)、深拷贝(Deep Copy)、延迟拷贝(Lazy Copy)。 二、浅拷贝 1、什么是浅拷贝 浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着

  • 我们有一个PDF链接,可以通过chrome内置的PDF查看器在浏览器中打开。我们正在尝试验证此PDF中的文本,无需使用PDFBox或将文件下载到本地系统。 我们的尝试使用将“CTRL A”和“CTRL C”(大写和小写版本)发送到浏览器。(这会导致一个大的蓝色框选择,而不是我们在尝试手动复制粘贴时看到的行选择)。我们认为两个命令之间有足够的2秒延迟,但文本内容不会显示在系统剪贴板中(通过粘贴到记事

  • 本文向大家介绍javascript深拷贝和浅拷贝详解,包括了javascript深拷贝和浅拷贝详解的使用技巧和注意事项,需要的朋友参考一下 一、数组的深浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的发生。 这是为什么呢? 因为如果只是简单的赋值,它只

  • 本文向大家介绍深拷贝与 浅拷贝的区别?相关面试题,主要包含被问及深拷贝与 浅拷贝的区别?时的应答技巧和注意事项,需要的朋友参考一下 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。