Visual Studio 2010 — Ищу большой файл в C ++ на Windows

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

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

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

Обновить::

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

Так.

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

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

2

Решение

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

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

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

3

Другие решения

Лучше всего использовать Win32 API напрямую, а не проходить через C RunTime.

использование CreateFile открыть файл и SetFilePointerEx искать

Функции, которые вы вызываете, в конечном итоге будут вызывать эти API. В Visual Studio у вас есть код CRT, чтобы вы могли _fseeki64 и, возможно, посмотреть, где это идет не так.

2

По вопросам рекламы [email protected]