gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 15:53:42 27 4
gpt4 key购买 nike

我发现在 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com