VS2010 で正確に 4294967295 バイトのファイルを開くと、seekg 関数が正しく動作しないことがわかりました。
私は単純なコードを使用しています:
#include <iostream>
#include <fstream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
std::ifstream file;
// cmd: fsutil file createnew tmp.txt 4294967295
file.open(L"c:/tmp.txt", ifstream::in | ifstream::binary);
if(!file.is_open())
return -1;
file.seekg(0, std::ios::end);
auto state = file.rdstate();
// this condition shoots only when size of the file is equal to 4294967295
if((state & ifstream::failbit)==ifstream::failbit)
{
std::cout << "seekg failed";
}
// after seekg failed, tellg returns 0
std::streampos endPos = file.tellg();
return 0;
}
4294967294 と 4294967296 のファイルを使用した同じコードは問題なく動作しています。
誰かがこの問題の解決策を知っていますか?
アップデート:
その問題はここにあるようです:
template<class _Statetype>
class fpos
{
__CLR_OR_THIS_CALL operator streamoff() const
{ // return offset
return ((streamoff)(_Myoff + _FPOSOFF(_Fpos)));
}
}
正確に
_FPOSOFF(_Fpos)
どこ
#define _FPOSOFF(fp) ((long)(fp))
したがって、 4294967295 を取り、それを -1 に変換します!
つまり、そのようなコードは失敗します
//returns -1, even if sizeof(fpos_t)=8
fpos_t pos = _FPOSOFF(4294967295);
_Myoff、_Fpos、streamoffset は 64 ビットです
すべての型が 64 ビットであるのに、なぜこの変換を行うのでしょうか!? 何も思いつきません ))