[C++, STL] Reusing an fstream object

Started by
7 comments, last by swiftcoder 14 years, 9 months ago
I'm having a strange problem... simplified here to show I/O parts only.

class MyClass
{
 fstream file;
 void loadFile(const string &path);
};

void MyClass::loadFile(const string &path)
{
 if(file.is_open())
 {
  file.close();
 }

 file.open(path);
 if(file.fail())
 {
   OH NO!!!
 }
}
When I call loadFile a 2nd time on the same MyClass instance,with the same path, opening the file fails. I checked and file.close() IS being called as expected. What could be causing it?
Advertisement
My guess is there's a race condition between the closing and reopening of the file. If you wait a little while before opening, or if you make repeated attempts, then you'll probably acquire the stream. If you know you're reopening a file then you could just not close it and seek the get pointer back to the start.
Quote:Original post by dmatter
My guess is there's a race condition between the closing and reopening of the file. If you wait a little while before opening, or if you make repeated attempts, then you'll probably acquire the stream. If you know you're reopening a file then you could just not close it and seek the get pointer back to the start.


The file isn't always the same path, that's just what I was testing... when the user selects to open a file we first close the old one as part of the opening process.
Most likely the eof and fail bit are set when you are done with the input. You can clear those error bits... or just use a new fresh filestream.
Roughlty speaking, you don't. Closing and then reopening a file doesn't reset all of the necessary flags, so if the fail() was true before reusing, it will still be true. There use to be a C++ faq lite entry on this, but I can't seem to find it.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Ah, I didn't consider those bits would remain set. I figured calling open() would reset them. Will try that, sounds logical.
Quote:Original post by d000hg
Ah, I didn't consider those bits would remain set. I figured calling open() would reset them.
I have no idea why it doesn't reset them - it definitely should [smile]

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

I strongly recommend not attempting to reuse the stream object, and in fact not keeping it as a data member, but just using a local variable where needed. What are you hoping to accomplish otherwise? Why would you need to keep the stream open between loadFile calls? (Do you even need to remember a file name?)
Quote:Original post by swiftcoder
There use to be a C++ faq lite entry on this, but I can't seem to find it.
I was looking on the wrong FAQ [smile]

The entry is here: http://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.stream_reopening_fails

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement