Ищем большой файл в С++ в Windows

Я пишу небольшую утилиту для анализа файловой системы xfs в Windows. Для образа небольшого размера ‹5 ГБ моя утилита работает нормально: я могу перечислить все файлы и каталоги. Но когда я пытаюсь разобрать большой образ xfs > 30 ГБ. Это дает неправильные результаты. Я использую _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;
    }

Однако вышеуказанная функция приводит меня в неправильное положение. Например, когда я хочу найти группу номер = 2 с m_fileSystemInfo.SizeOfBlockGroup = 2043982 и m_fileSystemInfo.BlockSize = 4096.

Я ожидаю currPrt = 2043982*4096*2 = 16744300544 (0x3E609C000), но возвращается _ftelli64 (0xE609C000). Пожалуйста, подскажите, что может пойти не так. Также, пожалуйста, посоветуйте, как лучше всего работать с большими файлами в Windows на С++.

Обновлять::

Я обнаружил, что seekOffset ограничивается 8154365952 (0x1e609c000) вместо фактического значения 16744300544 (0x3e609c000), несмотря на то, что я использую __int64.

So.

_int64 seekOff = (_int64)(grpNum*m_fileSystemInfo.SizeOfBlockGroup*m_fileSystemInfo.BlockSize) = 2*2043982*4096 дает 8154365952 вместо 16744300544.

Я не уверен, в чем может быть причина, так как все находится в __int64.


person praks411    schedule 15.11.2013    source источник


Ответы (2)


По-видимому, проблема была с вычислением смещения поиска. Это генерировало целочисленное переполнение. Следовательно, мне нужно преобразовать все в __int64, хотя я работаю над 64-битным приложением. Я думал, что компилятор может сделать это за меня.

__int64 grpNum = 2;
__int64 sizeOfBlockGroup = 2043982;
__int64 blockSize = 4096;
__int64 seekOffSet = grpNum*sizeOfBlockGroup*blockSize;

который отлично работает с _fseeki64 и __ftelli64.

person praks411    schedule 15.11.2013
comment
В модели памяти, используемой для 64-битных окон, указатели являются 64-битными, а целые числа — 32-битными. Кроме того, вам не нужно делать все значения __int64, вам просто нужно убедиться, что если A * B больше 32 бит, то либо A, либо B равно __int64. - person Stuart; 16.11.2013