c++ - seekg 无法正确处理 4294967295 字节的文件

标签 c++ visual-studio-2010 seekg

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

最佳答案

流实现内部有一个常量“_BADOFF”,它等于 0xffffffff,当查找失败时返回。在这种情况下,搜索成功,但搜索的返回值等于失败代码,这会导致流包装器错误地设置其失败代码。

_BADOFF 被定义为 64 位类型,它只是被分配了一个愚蠢的值。

作为变通方法,您可以查找 1 个字节的短字节,然后读取一个字节。

file.seekg(-1, std::ios::end);
char temp; file >> temp;

但是请注意,此错误会在任何时候查找特定文件偏移量时出现,因此如果您在随机位置中查找较大的文件,它仍然可能是一个问题。例如,如果您的文件大一个字节,此 -1 查找将失败,因此这不是通用解决方案。

OP 扩展了他们的问题,所以我将扩展我的答案。是的,查找值是在比较之前使用不安全的转换转换的。这似乎并不影响在文件中超出该点进行搜索的能力,因为它仅用于与错误值进行比较——流中仍然具有正确的偏移量。然而,它似乎首先是 _BADOFF 可疑的根本原因,因为 _BADOFF 在源代码中设置为“-1”,并且将遭受相同的转换,截断为 0xffffffff。

因此,库的修复可能是修复类型转换(假设这样做没有其他副作用),但为了解决这个问题,你只需要避免寻找底部的位置设置了 32 位。从我所见,它会超越那个 OK。

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

相关文章:

c# - 未知项目类型 GUID

C++ 困惑。从文本文件中读取整数。转换为 ASCII

c++ - #include<线程>,错误无法打开源文件 "thread"

visual-studio-2010 - VS2010禁用T4模板验证

c++ - ifstream seekg 有什么问题

c++ - 在ifstreams中使用seekg保持有效位置

c++ - 如何使用 grep 或 IDE 在代码库中查找移动构造函数?

c++ - OpenMP 开销计算

c++ - 使用 shared_ptr 启动 std::thread