我正在尝试用 C 读取 24 GB XML 文件,但它不起作用。我在读入时使用 ftell() 打印出当前位置,但是一旦它达到足够大的数字,它就会回到一个小数字并重新开始,甚至从未通过文件获得 20%。我认为这是用于存储位置(长)的变量范围的问题,根据http://msdn.microsoft.com/en-us/library/s3f49ktz(VS .80).aspx,而我的文件大小为 25,000,000,000 字节。long long 应该可以工作,但是我将如何更改我的编译器(Cygwin / mingw32)使用的内容或让它拥有 fopen64?
6 回答
You might try using the OS provided file functions CreateFile and ReadFile. According to the File Pointers topic, the position is stored as a 64bit value.
该ftell()
函数通常返回一个,在 32 位系统上unsigned long
最多只能达到 2 32字节 (4 GB)。因此,您无法将 24 GB 文件的文件偏移量放入 32 位long
.
您可能有ftell64()
可用的功能,或者标准fgetpos()
功能可能会向您返回更大的偏移量。
Unless you can use a 64-bit method as suggested by Loadmaster, I think you will have to break the file up.
This resource seems to suggest it is possible using _telli64(). I can't test this though, as I don't use mingw.
我不知道在一个文件中执行此操作的任何方法,有点破解但如果正确拆分文件不是一个真正的选择,您可以编写一些临时拆分文件的函数,一个使用 ftell () 在文件中移动并在 ftell() 到达分割点时将其交换到一个新文件,然后在退出之前将另一个文件缝合在一起。一种绝对拙劣的方法,但如果没有更好的解决方案出现,它可能是完成工作的一种方式。
我找到了答案。而不是使用 fopen、fseek、fread、fwrite... 我正在使用 _open、lseeki64、读、写。而且我能够在 > 4GB 的文件中写入和查找。
编辑:似乎后者的功能比前者慢约 6 倍。我会给任何能解释这一点的人赏金。
编辑:哦,我在这里了解到 read() 和朋友没有缓冲。 read() 和 fread() 有什么区别?
即使 Microsoft C 库中的 ftell() 返回 32 位值,因此一旦达到 2 GB 显然会返回虚假值,仅读取文件仍然可以正常工作。还是您也需要在文件中四处寻找?为此,您需要 _ftelli64() 和 _fseeki64()。
请注意,与某些 Unix 系统不同,您在打开文件时不需要任何特殊标志来指示它处于某种“64 位模式”。底层的 Win32 API 可以很好地处理大文件。