【问题标题】:2GB limit on file size when using fwrite in C?在 C 中使用 fwrite 时文件大小限制为 2GB?
【发布时间】:2009-04-08 16:09:38
【问题描述】:

我有一个简短的 C 程序,它会写入文件直到磁盘上没有更多空间:

#include <stdio.h>

int main(void) {
  char c[] = "abcdefghij";
  size_t rez;
  FILE *f = fopen("filldisk.dat", "wb");
  while (1) {
    rez = fwrite(c, 1, sizeof(c), f);
    if (!rez) break;
  }
  fclose(f);
  return 0;
}

当我运行程序时(在 Linux 中),当文件达到 2GB 时它会停止。

由于 FILE 结构或其他原因,是否存在内部限制?

谢谢。

【问题讨论】:

  • 这听起来像是 32 位整数的正 1/2。
  • 你的硬盘格式化成哪个文件系统?
  • Linux 说“vfat”,我认为是 FAT32。它是一个 4GB 的闪存驱动器,最初(几乎)是空的。
  • vfat (FAT32) 对每个文件都有 2GB 的限制,不管你用什么来编码。
  • support.microsoft.com/kb/314463 XP 的 FAT 文件大小限制为 4GB-1B。我以为 Linux 的 vfat 会限制在 2GB,但现在阅读源代码我想我错了。

标签: c filesystems fwrite fat32


【解决方案1】:

在 32 位系统上(即操作系统为 32 位),默认情况下,fopen 和 co 被限制为 32 位大小/偏移量/等...您需要启用大文件支持,或使用 *64位选项:

http://www.gnu.org/software/libc/manual/html_node/Opening-Streams.html#index-fopen64-931

那你的fs需要支持这个,但是除了fat等原始fs,都支持创建大于2gb的文件。

【讨论】:

    【解决方案2】:

    当文件达到 2GB 时停止。

    是否存在内部限制,由于 文件结构,还是什么?

    这是由于 libc(标准 C 库),它在 x86 (IA-32) Linux 系统上默认是由 glibc(GNU 的 C 库)提供的 32 位函数。所以默认情况下,file stream size 基于 32 位 -- 2^(32-1)。

    如需使用Large File Support,请参阅网页。

    #define _FILE_OFFSET_BITS  64
    /* or more commonly add -D_FILE_OFFSET_BITS=64 to CFLAGS */
    
    #include <stdio.h>
    
    int main(void) {
      char c[] = "abcdefghij";
      size_t rez;
      FILE *f = fopen("filldisk.dat", "wb");
      while (1) {
        rez = fwrite(c, 1, sizeof(c), f);
        if ( rez < sizeof(c) ) { break; }
      }
      fclose(f);
      return 0;
    }
    

    注意:大多数系统期望 fopen(和 off_t)基于 2^31 文件大小限制。将它们替换为 off64_tfopen64 可以明确这一点,并且根据使用情况可能是最好的方法。但一般不推荐,因为它们是非标准的。

    【讨论】:

    • 永远不要使用 *64 函数。始终使用-D_FILE_OFFSET_BITS=64 编译所有程序。
    • 大部分同意,因为 *64 函数不可移植,并且在任何标准中都没有明确定义,但它们确实明确了要求,这在某些有限的情况下可能是好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2010-12-02
    • 2011-03-07
    • 1970-01-01
    相关资源
    最近更新 更多