我正在编写一个小实用程序来解析Windows上的xfs文件系统。 对于小尺寸图像< 5GB我的实用程序工作正常:我能够列出所有文件和目录。 但是当我尝试解析大型xfs图像时> 30GB。它给出了错误的结果。 我正在使用_fseeki64和_ftelli64来寻找和阅读特定块。 我注意到的一件事是_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寻找组号= 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中的所有内容。
答案 0 :(得分:3)
显然问题在于寻找偏移的计算。它正在生成整数溢出。 因此,我必须将所有内容转换为__int64,尽管我正在使用64位应用程序。我在想,编译器可能会为我做这件事。
__int64 grpNum = 2;
__int64 sizeOfBlockGroup = 2043982;
__int64 blockSize = 4096;
__int64 seekOffSet = grpNum*sizeOfBlockGroup*blockSize;
适用于_fseeki64和__ftelli64。
答案 1 :(得分:2)
您最好的选择是直接使用Win32 API,而不是通过C RunTime。
使用CreateFile
打开文件,SetFilePointerEx
寻找
您正在调用的函数最终会调用这些API。在Visual Studio中,您有CRT代码,因此您可以进入_fseeki64
并可能看到它出错的地方。