在Windows上用c ++寻找大文件

时间:2013-11-15 10:40:44

标签: c++ visual-studio-2010 winapi xfs

我正在编写一个小实用程序来解析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中的所有内容。

2 个答案:

答案 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并可能看到它出错的地方。