seekg()神秘失败 [英] seekg() failing mysteriously
问题描述
我有一个2884765579字节的文件.对此函数进行了双重检查,该函数返回该数字:
I have a 2884765579 bytes file. This is double checked with this function, that returns that number:
size_t GetSize() {
const size_t current_position = mFile.tellg();
mFile.seekg(0, std::ios::end);
const size_t ret = mFile.tellg();
mFile.seekg(current_position);
return ret;
}
然后我做
mFile.seekg(pos, std::ios::beg);
// pos = 2883426827, which is < than the file size, 2884765579
这将设置故障位. errno
不变.我可以采取什么步骤来解决此问题?
This sets the failbit. errno
is not changed. What steps can I take to troubleshoot this?
我绝对确定:
- 文件大小实际上是2884765579
-
pos
确实是2884765579 - 未在.seekg()之前设置故障位
- 在.seekg()之后设置故障位,并且在两者之间不进行其他调用
- 使用二进制标志打开文件
- The file size is really 2884765579
pos
is really 2884765579- The failbit is not set before .seekg()
- The failbit is set right after .seekg() and no other calls are made in between
- The file is opened with the binary flag
编辑:以防有人遇到相同的问题.使用我编写的这段代码(仅适用于Windows),可以为您减少很多麻烦:
EDIT: in case someone runs into the same problem.. Use this code I wrote (works on windows only) and many less headaches for you:
class BinaryIFile
{
public:
BinaryIFile(const string& path) : mPath(path), mFileSize(0) {
mFile = open(path.c_str(), O_RDONLY | O_BINARY);
if (mFile == -1)
FATAL(format("Cannot open %s: %s") % path.c_str() % strerror(errno));
}
~BinaryIFile() {
if (mFile != -1)
close(mFile);
}
string GetPath() const { return mPath; }
int64 GetSize() {
if (mFileSize)
return mFileSize;
const int64 current_position = _telli64(mFile);
_lseeki64(mFile, 0, SEEK_END);
mFileSize = _telli64(mFile);
_lseeki64(mFile, current_position, SEEK_SET);
return mFileSize;
}
int64 Read64() { return _Read<int64>(); }
int32 Read32() { return _Read<int32>(); }
int16 Read16() { return _Read<int16>(); }
int8 Read8() { return _Read<int8>(); }
float ReadFloat() { return _Read<float>(); }
double ReadDouble() { return _Read<double>(); }
void Skip(int64 bytes) { _lseeki64(mFile, bytes, SEEK_CUR); }
void Seek(int64 pos) { _lseeki64(mFile, pos, SEEK_SET); }
int64 Tell() { return _telli64(mFile); }
template <class T>
T Read() { return _Read<T>(); }
void Read(char *to, size_t size) {
const int ret = read(mFile, (void *)to, size);
if ((int)size != ret)
FATAL(format("Read error: attempted to read %d bytes, read() returned %d, errno: %s [we are at offset %d, file size is %d]") % size % ret % strerror(errno) % Tell() % GetSize());
}
template <class T>
BinaryIFile& operator>>(T& val) { val = _Read<T>(); return *this; }
private:
const string mPath;
int mFile;
int64 mFileSize;
template <class T>
T _Read() { T ret; if (sizeof(ret) != read(mFile, (void *)&ret, sizeof(ret))) FATAL("Read error"); return ret; }
};
推荐答案
您可以在给定位置之前搜索,因此pos已签名.尝试使用大小为0x7fffffff和0x80ffffff的文件进行尝试,看看后者是否触发了问题,这是我的猜测.
You can seekg before a given position, so pos is signed. Try it with files of size 0x7fffffff and 0x80ffffff and see if the latter triggers the problem, that's my guess.
这篇关于seekg()神秘失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!