Windows で xfs ファイルシステムを解析するための小さなユーティリティを作成しています。5GB 未満の小さなサイズのイメージの場合、ユーティリティは正常に動作します。すべてのファイルとディレクトリを一覧表示できます。しかし、30 GB を超える大きな xfs イメージを解析しようとすると、. それは間違った結果を与えています。特定のブロックを読み取るためにシークと fread に _fseeki64 と _ftelli64 を使用しています。私が気づいたことの 1 つは、_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 でグループ番号 = 2 をシークしたい場合。
私は currPrt = 2043982*4096*2 = 16744300544 (0x3E609C000) を期待していますが、_ftelli64 は (0xE609C000) を返しています。何が問題なのかを提案してください。また、Windows で大きなファイルを C++ で処理する最善の方法を教えてください。
アップデート::
__int64 を使用しているにもかかわらず、seekOffset が実際の値 16744300544 (0x3e609c000) ではなく 8154365952 (0x1e609c000) に制限されていることがわかりました。
そう。
_ int64 seekOff = ( _int64)(grpNum*m_fileSystemInfo.SizeOfBlockGroup*m_fileSystemInfo.BlockSize) = 2*2043982*4096 は、16744300544 ではなく 8154365952 を与えています。
すべてが__int64にあるため、何が原因なのかわかりません。