简而言之: C中的跨操作系统,大文件支持是可怕的。
目标:我试图让“单向”(最可能是基于宏的)允许32位AND 64位具有大文件支持。理想情况下,使用typedef,#ifdef,#(n)定义等宏包装器可以允许以#include库或一组定义的宏的形式支持基本的大文件。
研究:POSIX的文件操作在BSD / Mac / Linux上运行良好,32位和64位IO,文件大小超过典型的2 ^ 31大小,但即使在Windows上使用clang或mingw由于M $愚蠢地实现POSIX,我无法利用这些调用(如果这就是我们想要的那个......)。我倾向于在Windows上使用CreateFile(),ReadFile(),WriteFile(),但这在方法和数据类型方面与POSIX的open()/ read()/ write()/ close()/ etc完全不同。使用
问题:在我的键盘和几本教科书上敲击之后,我决定对你们所有人进行调查:你们这些人/女孩如何实现跨操作系统文件支持大文件的I / O?
P.S。我有研究链接:
答案 0 :(得分:1)
答案 1 :(得分:0)
尽管我们都喜欢讨厌M $因为他们糟糕的标准一致性,但这个实际上是ISO C委员会的错。最初,他们将size_t用于所有文件参数,但size_t是根据ALU /内存架构选择的,而不是基于操作系统文件处理功能。当每个人都切换到64位CPU时,MS坚持使用32位长,这是完全允许的,但仍然符合要求,但现在他们的文件比他们最大的算术类型更大。
请注意,这最终在C99中解决了,但MSVC C99支持基本上不存在。
但是,在内部,它们确实使用64位指针来跟踪文件中的位置。问题是由于不幸的cstdlib API,你不能对大于32位的任何东西使用“fseek”或“ftell”。
为了演示Windows确实使用64位文件指针,当使用MSVC ++编译时,此代码实际上将按预期工作,并将在硬盘驱动器上生成40GB文件(无符号长度为32位)。
#include <stdio.h>
int main(int argc, char **argv) {
FILE *my_file;
unsigned long i, j;
my_file = fopen("bigfile.bin", "wb");
for(i = 0; i < 10; i++) {
for(j = 0; j < (1024 * 1024 * 1024); j++) {
fwrite(&j, sizeof(j), 1, my_file);
}
}
fclose(my_file);
return 0;
}
那么这对你有什么帮助?好吧,MS提供了自己的非标准API,允许64位fseek()和ftell()
https://msdn.microsoft.com/en-us/library/75yw9bf3.aspx
另外,您实际上可以通过常规fseek()以递增的方式移动文件指针...基本上如果你去了:
fseek(my_file, 0, SEEK_SET);
for(i = 0; i < 10; i++) {
fseek(my_file, (1024 * 1024 * 1024), SEEK_CUR);
}
它会有效地将文件指针移动到10GB标记。
但是使用ftell(),你可能没有使用MS API就搞砸了。
TL; DR - fopen(),fread()和fwrite()在大型文件&gt; 2GB的MSVC上工作,但ftell()和fseek()没有,因为API没有正确设计。
答案 2 :(得分:0)