在 Windows 上用 C++ 寻找大文件
Posted
技术标签:
【中文标题】在 Windows 上用 C++ 寻找大文件【英文标题】:Seeking large file in c++ on windows 【发布时间】:2013-11-15 10:40:43 【问题描述】:我正在编写一个小工具来解析 Windows 上的 xfs 文件系统。 对于 30GB 的大型 xfs 图像时。它给出了错误的结果。 我正在使用 _fseeki64 和 _ftelli64 来寻找和 fread 来阅读特定的块。 我注意到的一件事是 _fseeki64 工作不正常。 下面是我的搜索函数,它搜索特定的组号和块号。
int FileSystemReadXFS::SeekToGroupBlock(uint16_t grpNum, uint64_t blockNum)
int error = -1;
//Seek to beginning
if(_fseeki64(m_fileSystemInfo.fp, (__int64)0, SEEK_SET) != 0)
PRINT_SEEK_ERROR;
goto BAILOUT;
__int64 currPtr = 0;
//Seek to destination group
if(grpNum > 0)
if(_fseeki64(m_fileSystemInfo.fp, (__int64)(grpNum*m_fileSystemInfo.SizeOfBlockGroup*m_fileSystemInfo.BlockSize), SEEK_SET))
PRINT_SEEK_ERROR;
goto BAILOUT;
currPtr = _ftelli64(m_fileSystemInfo.fp);
//Seek to destination block in group
if(blockNum > 0)
if(_fseeki64(m_fileSystemInfo.fp, (__int64)(blockNum*m_fileSystemInfo.BlockSize), SEEK_CUR))
PRINT_SEEK_ERROR;
goto BAILOUT;
currPtr = _ftelli64(m_fileSystemInfo.fp);
error = 0;
BAILOUT:
return error;
但是上面的函数把我带到了错误的位置。 例如,当我想用 m_fileSystemInfo.SizeOfBlockGroup = 2043982 对 number = 2 进行分组时 和 m_fileSystemInfo.BlockSize = 4096。
我期待 currPrt = 2043982*4096*2 = 16744300544 (0x3E609C000),但 _ftelli64 正在返回 (0xE609C000)。 请提出可能出了什么问题。另外请建议在 c++ 中处理 Windows 上的大文件的最佳方法是什么。
更新::
我发现 seekOffset 被限制为 8154365952 (0x1e609c000) 而不是实际 尽管我使用 __int64,但值为 16744300544 (0x3e609c000)。
所以。
_int64 seekOff = (_int64)(grpNum*m_fileSystemInfo.SizeOfBlockGroup*m_fileSystemInfo.BlockSize) = 2*2043982*4096 给出 8154365952 而不是 16744300544。
我不确定原因是什么,因为一切都在 __int64 中。
【问题讨论】:
【参考方案1】:显然问题出在寻找偏移量的计算上。它正在产生整数溢出。 因此,即使我正在处理 64 位应用程序,我也必须将所有内容都转换为 __int64。我在想编译器也许可以为我做到这一点。
__int64 grpNum = 2;
__int64 sizeOfBlockGroup = 2043982;
__int64 blockSize = 4096;
__int64 seekOffSet = grpNum*sizeOfBlockGroup*blockSize;
它适用于 _fseeki64 和 __ftelli64。
【讨论】:
在用于 64 位窗口的内存模型中,指针是 64 位,而整数是 32 位。此外,您不必将所有值设为 __int64,您只需确保如果 A * B 大于 32 位,则 A 或 B 为 __int64。【参考方案2】:最好的办法是直接使用 Win32 API,而不是通过 C RunTime。
使用CreateFile
打开文件,使用SetFilePointerEx
寻找
无论如何,您调用的函数最终都会调用这些 API。在 Visual Studio 中,您有 CRT 代码,因此您可以进入 _fseeki64
并可能查看哪里出错了。
【讨论】:
我发现 2*2043982*4096 的偏移量计算被限制为 8154365952 而不是 16744300544 的实际值。我在大多数地方都使用了 __int64 但它没有帮助。以上是关于在 Windows 上用 C++ 寻找大文件的主要内容,如果未能解决你的问题,请参考以下文章