2

当我运行这段代码时,open 和 seekg 和 tellg 操作都成功了。但是当我阅读它时,它失败了,eof、bad、fail 位是 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;
}

4

2 回答 2

4

引用Apache C++ 标准库用户指南

标志 std::ios_base::badbit 指示底层流缓冲区存在问题。这些问题可能是:
  • 内存不足。没有可用于创建缓冲区的内存,或者由于其他原因(例如从流外部提供),缓冲区的大小为 0,或者流无法为其自己的内部数据分配内存,如 std::ios_base:: iword() 和 std::ios_base::pword()。
  • 底层流缓冲区引发异常。流缓冲区可能会失去其完整性,例如内存不足、代码转换失败或来自外部设备的不可恢复的读取错误。流缓冲区可以通过抛出异常来指示完整性丢失,该异常被流捕获并导致在流的状态中设置坏位。

这并不能告诉你问题是什么,但它可能会给你一个开始的地方。

请记住,在尝试读取并失败之前,通常不会设置 EOF 位。(换句话说,rifile.good调用后检查seekg可能不会完成任何事情。)

正如 Andrey 建议的那样,检查errno(或使用特定于操作系统的 API)可能会让您解决根本问题。 这个答案有这样做的示例代码。

旁注:因为rifile是本地对象,所以完成后不需要关闭它。理解这一点对于理解RAII很重要,RAII是 C++ 中的一项关键技术。

于 2010-03-30T18:04:54.777 回答
3

试试老errno。它应该显示错误的真正原因。不幸的是,没有 C++ish 方法可以做到这一点。

于 2010-03-30T17:51:12.273 回答