我已经定义了 _LARGEFILE64_SOURCE_FILE_OFFSET_BITS 64 支持超过 2G 的 open() 文件。这似乎没问题。

但是如果我尝试一次 write() 超过 2G 的数据(例如 64G ),write() 将返回一个远小于 64G 的值(正好是 2147479552)。我猜 write() 一次只能写入小于 2G 的数据。

这是我的代码:

#define _GNU_SOURCE
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <mmap.h>

#define SPACE_SIZE 68719476736

int main()
{
    ssize_t err;
    void* zeros;
    int fd = open64("./test", O_CREAT|O_RDWR|O_LARGEFILE, 0644);
    assert(fd != -1);
    int zero_fd = open("/dev/zero", O_RDWR);
    assert(zero_fd != -1);

    zeros = mmap(NULL, SPACE_SIZE, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, zero_fd, 0);
    assert(zeros != (void *)-1);
    err = write(fd, zeros, SPACE_SIZE);
    assert(err == SPACE_SIZE);   // Received SIGABRT, err = 2147479552
    munmap(zeros, SPACE_SIZE);
}

如何一次写入()超过2G的数据?

补充资料:
readelf -h ./a.out 的结果。 a.out 是我的程序名
ELF Header:
Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class:                             ELF64
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              DYN (Shared object file)
Machine:                           Advanced Micro Devices X86-64
Version:                           0x1
Entry point address:               0x660
Start of program headers:          64 (bytes into file)
Start of section headers:          6672 (bytes into file)
Flags:                             0x0
Size of this header:               64 (bytes)
Size of program headers:           56 (bytes)
Number of program headers:         9
Size of section headers:           64 (bytes)
Number of section headers:         29
Section header string table index: 28

最佳答案

事实上,这个事实在 man write 中有详细记录:



因此,如果您使用的是 Linux,则无法在对 write() 的一次调用中写入 64GB。

但是,您可以通过寻求偏移 64GB-1 并写入单个 NUL 字节来创建一个似乎包含 64GB NUL 字节的文件。 (或者,正如@o11c 在评论中指出的那样,您可以使用 ftruncate(fd, SPACE_SIZE); 。)其中任何一个都会创建一个稀疏文件,该文件实际上不会占用太多磁盘空间,但它的行为就像是 64GB 的 NUL。

关于c - 如何一次写入()超过2G的数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50302388/

10-11 21:13