我发现在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位,为什么要进行这种转换呢?我不知道 ))

最佳答案

这确实是Visual C++ 2010中的错误。两年前在Microsoft Connect上进行了报道:" std::fstream use 32-bit int as pos_type even on x64 platform"(错误的标题不正确;症状实际上是由_FPOSOFF中的此错误引起的)。

此错误已在Visual C++ 2012中修复,其中_FPOSOFF定义为:

#define _FPOSOFF(fp)  ((long long)(fp))

如果可以的话,建议您升级到Visual C++ 2012。

关于c++ - seekg无法正确处理4294967295字节的文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13837810/

10-09 07:34