【问题标题】:C working with big files, fseek and freadC 处理大文件、fseek 和 fread
【发布时间】:2021-07-21 05:12:31
【问题描述】:

我正在编写一个程序,我可能需要访问大于~2GB 的文件。只使用 fseek 和 fread 而不使用 ftell 可以处理更大的文件吗?

int main() {
  unsigned long long int len;
  unsigned char *buffer; /* i know its not initialized */
  unsigned char *sbuffer = buffer;

  FILE *fp = fopen("test123", "rb");
  fread(fp, 8, 1, (void*) &len);

  while (len >= LONG_MAX) {
    fread(fp, 1, LONG_MAX, (void*) sbuffer);
    sbuffer += LONG_MAX;
    len -= LONG_MAX;
  }
  if (len) {
    fread(fp, 1, len, (void*) sbuffer);
  }
}

【问题讨论】:

  • 您通过读取文件的前 8 个字节来设置 len。但是,您永远在您的while 循环中减少它,因此您将永远循环。将len -= LONG_MAX; 添加到循环底部。但是,你真的应该这样做:while (len >= LONG_MAX) { unsigned long long cur = fread(fp, 1, LONG_MAX, (void *) sbuffer); if (cur != LONG_MAX) break; len -= cur; sbuffer += LONG_MAX; } 但是,LONG_MAX 在任何情况下都不是一个好的选择。使用较短的缓冲区(例如 64KB),因为您是在块中循环。
  • 您的 sn-p 中没有 fseek。 fread 的参数是 size_t,不是 long,它的最大值是 SIZE_MAX,如果小于 LONG_MAX,你就有麻烦了。缓冲区未初始化(很高兴你知道它,但它仍然是错误的)。没有错误处理。答案可能还取决于您的文件系统的功能。
  • 这是关于想法的,我不知道如何表示 fseek。但是我能不能继续用 SEEK_CUR 向前跳,并且 fread 也会移动指针
  • 顺序读取和相对查找的基本思想适用于(可能)所有主流操作系统上的大文件。但是,我在相关标准中看不到任何可以保证这一点的东西。您是对某些特定环境感兴趣,还是想要最大限度地便携的解决方案?
  • 主要是 Windows、Linux 和其他 Unix,所以没什么好混淆的。而且我想追求最大的便携性。

标签: c file io fread


【解决方案1】:

您可以使用 fread64fseek64 等的 64 位变体,也可以在包含标头之前使用 #define _FILE_OFFSET_BITS 64

【讨论】:

  • 这不是独立于平台的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
相关资源
最近更新 更多