【发布时间】: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,所以没什么好混淆的。而且我想追求最大的便携性。