当我运行此代码时,open和seekg和tellg操作都成功了。 但是当我读它时,它失败了,eof,bad,fail bit是0 1 1。
什么会导致文件损坏? 感谢
int readriblock(int blockid, char* buffer)
{
ifstream rifile("./ri/reverseindex.bin", ios::in|ios::binary);
rifile.seekg(blockid * RI_BLOCK_SIZE, ios::beg);
if(!rifile.good()){ cout<<"block not exsit"<<endl; return -1;}
cout<<rifile.tellg()<<endl;
rifile.read(buffer, RI_BLOCK_SIZE);
**cout<<rifile.eof()<<rifile.bad()<<rifile.fail()<<endl;**
if(!rifile.good()){ cout<<"error reading block "<<blockid<<endl; return -1;}
rifile.close();
return 0;
}
答案 0 :(得分:4)
引用Apache C++ Standard Library User's Guide:
标志std :: ios_base :: badbit表示底层流缓冲区存在问题。这些问题可能是:
- 内存不足。没有可用于创建缓冲区的内存,或者缓冲区由于其他原因(例如从流外部提供)而具有大小为0,或者流不能为其自己的内部数据分配内存,如std :: ios_base :: iword()和std :: ios_base :: pword()。
- 底层流缓冲区抛出异常。流缓冲区可能会失去其完整性,如内存不足或代码转换失败,或外部设备无法恢复的读取错误。流缓冲区可以通过抛出异常来指示这种完整性的丢失,该异常被流捕获并导致在流的状态中设置badbit。
这并没有告诉你问题是什么,但它可能会给你一个开始的地方。
请记住,在尝试读取并失败之前,通常不会设置EOF位。 (换句话说,在调用rifile.good
后检查seekg
可能无法完成任何事情。)
正如Andrey建议的那样,检查errno
(或使用特定于操作系统的API)可能会让您解决潜在的问题。 This answer有代码来执行此操作。
附注:由于rifile
是本地对象,因此您无需在完成后关闭它。理解这对于理解RAII很重要,这是C ++中的一项关键技术。
答案 1 :(得分:2)
尝试旧errno
。它应该显示错误的真正原因。遗憾的是,没有C ++方法可以做到这一点。