尝试在Linux上写入()大于2 GB的文件时出错

时间:2016-07-26 09:32:11

标签: c++ file posix mmap

我需要打开一个文件并通过mmap将其加载到共享内存中,但是如果该文件还不存在,我想打开它,写一些(假的)数据,然后mmap它。我在C中编写了以下函数,但是我在写入时遇到错误(见下文)。 (我知道mmap部分可能是错误的(数据被分配了两次!),但错误发生在此之前,所以它不应该对这个问题产生任何影响。)

// These 2 are global so they can be referenced in other functions.
int dfd = -1;
long* data = NULL;

void load_data(char* filename)
{
  dfd = open(filename, O_RDONLY);

  if (dfd == -1) {

    printf("Creating file %s\n", filename);

    dfd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);

    if (dfd == -1) {
      fprintf(stderr, "Couldn't create file %s\n", filename);
      perror("create");
      exit(1);
    }

    data = (long *) valloc(M * GB);

    if (data == nullptr) {
      fprintf(stderr, "Couldn't allocate %ld bytes", (M * GB));
      perror("malloc");
      exit(1);
    }

    for (size_t i = 0; i < M * GB / sizeof(long); ++i)
      data[i] = (long) i;

    printf("%d %p %ld\n", dfd, data, M * GB);

    ssize_t w = write(dfd, (void*) data, M * GB);

    if (w != M * GB) {
      fprintf(stderr, "Couldn't write %ld bytes to file %s\n", (M * GB), filename);
      fprintf(stderr, "Wrote %ld bytes\n", w);
      perror("write");
      exit(1);
    }
  }

  data = (long *) mmap(0, M * GB, PROT_READ, MAP_SHARED, dfd, 0);

  if (data == MAP_FAILED) {
    perror("mmap");
    exit(1);
  }
}

MacOS 64位上的输出和错误,Apple g ++:

Creating file bench2_datafile.bin
3 0x101441000 2147483648
Couldn't write 2147483648 bytes to file bench2_datafile.bin
Wrote -1 bytes
write: Invalid argument

任何指针?我一直在阅读开放和写作文档,并在互联网上寻找示例,但我似乎无法克服这个错误。

从评论中受益:

RHEL 6上的输出,g ++ 4.8:

Creating file bench2_datafile.bin
3 0x7f79048af000 2147483648
write: Success
Couldn't write 2147483648 bytes to file bench2_datafile.bin
Wrote 2147479552 bytes

和2147479552确实是ls。

中的文件大小

此外,它适用于1 GB的Mac - 但它耗尽了2 GB的蒸汽。哦 - 好吧 - 我真正的目标是Linux无论如何,在我得到错误之前在Mac上工作更方便: - )

1 个答案:

答案 0 :(得分:2)

许多平台使用32位值作为文件位置。此外,接口需要对值进行签名。这意味着,只要您想处理大于2 GB的文件,就会遇到麻烦。

某些平台提供非标准功能来处理较大的文件。

您需要查看平台文档,了解您要定位的平台的内容。