我正在编写一个小实用程序来解析windows上的xfs文件系统。对于小于5GB的图像,我的实用程序工作得很好:我能够列出所有文件和目录。但是当我试图解析大型xfs映像时,却超过了30 to。它带来了错误的结果。我使用_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和m_fileSystemInfo.BlockSize = 4096对number =2进行分组时。
我期望currPrt = 2043982*4096*2 = 16744300544 (0x3E609C000),但_ftelli64正在返回(0xE609C000)。请提出可能出错的建议。另外,请建议在c++中处理窗口上的大文件的最佳方法是什么。
最新情况:
我发现,尽管我使用了seekOffset,但__int64的实际值为8154365952 (0x1e609c000),而不是实际值16744300544 (0x3e609c000)。
所以。
(_int64)(grpNum*m_fileSystemInfo.SizeOfBlockGroup*m_fileSystemInfo.BlockSize) = 2*2043982*4096是8154365952,而不是16744300544。
我不知道在__int64中有什么原因。
发布于 2013-11-15 13:15:13
显然,问题在于寻求偏移量的计算。它会产生整数溢出。因此,我必须将所有内容转换为__int64,尽管我正在处理64位应用程序。我在想编译器也许能帮我做到这一点。
__int64 grpNum = 2;
__int64 sizeOfBlockGroup = 2043982;
__int64 blockSize = 4096;
__int64 seekOffSet = grpNum*sizeOfBlockGroup*blockSize;这在_fseeki64和__ftelli64中运行得很好。
发布于 2013-11-15 11:20:09
最好的选择是直接使用Win32 API,而不是通过C RunTime。
使用CreateFile打开文件,使用SetFilePointerEx查找
您正在调用的函数最终将调用这些API。在Visual中,您有CRT代码,因此您可以进入_fseeki64,并可能看到它出错的地方。
https://stackoverflow.com/questions/19999126
复制相似问题