加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 09:20:44 所属栏目:百科 来源:网络整理
导读:我已经定义了_LARGEFILE64_SOURCE和_FILE_OFFSET_BITS 64 ?支持超过2G的open()文件.这似乎没问题. 但是如果我一次尝试写入()数据超过2G(例如64G),write()将返回一个远小于64G的值(完全是2147479552).我猜write()只能一次写入小于2G的数据. 这是我的代码: #d
我已经定义了_LARGEFILE64_SOURCE和_FILE_OFFSET_BITS 64
?支持超过2G的open()文件.这似乎没问题.

但是如果我一次尝试写入()数据超过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);
}

如何一次写2(2)以上的数据?

补充资料:

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

解决方法

事实上,这个事实在人类写得很清楚:

On Linux,write() (and similar system calls) will transfer at most 0x7ffff000 (2,147,479,552) bytes,returning the number of bytes actually transferred. (This is true on both 32-bit and 64-bit systems.)

因此,如果您使用Linux,则无法在一次调用write()时写入64GB.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读