我正在编写一个小实用程序来解析 Windows 上的 xfs 文件系统。 对于 <5GB 的小尺寸图像,我的实用程序运行良好:我能够列出所有文件和目录。 但是当我尝试解析大于 30GB 的大型 xfs 图像时。它给出了错误的结果。 我正在使用 _fseeki64 和 _ftelli64 来查找和读取特定 block 。 我注意到的一件事是 _fseeki64 没有正常工作。 下面是我的查找函数,它查找特定的组号和 block 号。
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) 而不是实际的 16744300544 (0x3e609c000) 的值尽管我使用了 __int64。
所以。
_int64 seekOff = (_int64)(grpNum*m_fileSystemInfo.SizeOfBlockGroup*m_fileSystemInfo.BlockSize) = 2*2043982*4096 给出 8154365952 而不是 16744300544。
我不确定是什么原因,因为一切都在 __int64 中。
最佳答案
显然问题出在搜索偏移量的计算上。它正在产生整数溢出。 因此,即使我正在处理 64 位应用程序,我也必须将所有内容都转换为 __int64。我在想编译器也许可以为我做这件事。
__int64 grpNum = 2;
__int64 sizeOfBlockGroup = 2043982;
__int64 blockSize = 4096;
__int64 seekOffSet = grpNum*sizeOfBlockGroup*blockSize;
它适用于 _fseeki64 和 __ftelli64。
关于c++ - 在 Windows 上用 C++ 查找大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19999126/