read equivalent for filebuf?

霸气de小男生 提交于 2019-12-02 19:46:06

问题


typedef struct {
  char c[20];
  int i;
} header;

void foo(std::string s) {
  std::ifstream ifs(s.c_str(), std::ios_base::binary | std::ios_base::in);
  if (ifs) {
    std::filebuf* pbuf = ifs.rdbuf();
    pbuf->pubseekpos(std::ios_base::beg); 
    // ... ?
  }
}

I'm trying to read a file in binary mode the C++ way, I can't identify the right method to call for reading the bits from the file, there is a read for ifstream but if I'm supposed to use that method, what is the point of filebuf ?

To simplify things I have a struct that represents the order, the size and the fields of the header and I hope that there will be a method that would just keep and instance of this struct and write the bits in right fields just like fread from C.

Someone can clarify the point of filebuf and what method should I use when reading a file through an unformatted stream of data ?


回答1:


Just use basic_istream<>::read() to read raw, unformatted byte data:

void foo(std::string s) {
  std::ifstream ifs(s.c_str(), std::ios_base::binary | std::ios_base::in);
  if (ifs) {
    char buffer[20];
    if (!ifs.read(buffer, 20)) {
      // Handle error
    }
  }
}



回答2:


First, the real point of filebuf is that it derives from streambuf, and that an istream whose streambuf is a filebuf will behave largely like an ifstream. This is important; the >> operator aren't virtual, and since many of them aren't members, they cannot be virtual. All input must pass through the istream, not the ifstream that's derived from it. More generally, the ifstream can be thought of as just a convenience class; it's constructor provides the istream base class with a filebuf, its destructor destructs the filebuf, and it provides access to the functionality of filebuf which isn't present in the base streambuf.

That doesn't mean that you cannot use the streambuf directly, you can, and there are cases where it is appropriate. But if you do, you have to take care of the error handling. When you call istream::read asking for a certain number of bytes, and those bytes aren't there, istream::read will note the end of file, set the necessary error bits, and provide the count of what was actually read through istream::gcount. If you're reading byte by byte, and don't know how many bytes there might be, then all of that may not mean much (but you'll probably want to set eofbit if you see EOF). If you're trying to read a specific number of bytes (say a four byte integer), then istream:read will set the appropriate error bits if you cannot read four bytes, so you can easily test for the error.

EDIT

One additional comment: you should probably put the reading of the file in a separate process, which takes an std::istream&. You really don't want the reading code to know that it is dealing with an ifstream, rather than some other sort of stream. (Also: there's no need to seek if you've just opened the file.)




回答3:


there is a read for ifstream

Yes, and that's what you use to read unformatted data from the stream; hence the name.

if I'm supposed to use that method, what is the point of filebuf ?

It's used by the stream to handle low-level file access and buffering. You can access it if you need to mess around with those details, but usually there's no need to. You certainly wouldn't mess around with it if you just want to read from the stream.




回答4:


what is the point of filebuf ?

None, here.

I can't see why you're using it.

Until you do more complex operations, filebuf is an implementation detail.

(Sort of.)



来源:https://stackoverflow.com/questions/21049909/read-equivalent-for-filebuf

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!