开发者

What kinds of input streams can you call seekg on?

I have a function (legacy) that reads the first few lines of a file to determine its type, then closes and reopens the file so it can re-read the entire file using the correct interpreter. The gist is:

void readFile(const char *filename) {
  ifstream is(filename);
  Filetype ft = determineFileType(is);
  is.close();
  is.open(filename);
  parseFile(is, ft);
}

I needed a similar function that can work on an already-opened stream. I created a new function that takes an ostream & instead of a char *filename -- basically this:

void readFile(istream &is) {
  std::ios::streampos pos = is.tellg();
  Filetype ft = determineFileType(is);
  is.seekg(pos);
  parseFile(is, ft);
}

It seems to work when the istream is actually a stringstream or an fstream but I wonder if I'm just getting lucky. I also did a small test on seekg-ing std::cin and it worked, which surprised me.

So my question: what kinds of streams are you allowed to use seekg on? When will it fail? Spec references would be great -- I looked through and the stuff on seekg, pubseekpos, seekpos, seekoff weren't helpful at all.

开发者_运维百科

I'd like to reimplement the original function in terms of the new (as below), but I just don't know if that's safe.

void readFile(const char *filename) {
  ifstream is(filename);
  readFile(is);
  is.close();
}


The only real answer one can give is that it works where it works. In the case of std::stringbuf, it should work everywhere. In the case of std::filebuf, whether it works or not depends on the system; it will generally work if the filebuf is opened on an actual file, but will usually fail (perhaps silently, if the system doesn't report an error) for many other types of input: from a keyboard, or a named pipe, for example.

A more robust solution would be to cache the initial input, and re-read it from the cache.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜