sendfile64 только копия около 2 ГБ

Мне нужно использовать sendfile64 для копирования около 16 ГБ файлов. То, чего я достиг до сих пор, это

#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

Проблема в том, что я до сих пор не могу скопировать более 2 ГБ файла.

Может кто-нибудь указать мне, где моя ошибка?

4

Решение

Вы должны использовать цикл, чтобы скопировать все это, 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 флаг, который определяет, будет делать правильные вещи и преобразует off_t в off64_t, sendfile в sendfile64 и так далее, если эти типы и функции еще не являются 64-битными (например, в 32-битных архитектурах).

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]