Ahmad Siavashi
Ahmad Siavashi

Reputation: 999

Reopening a closed file stream

Consider the following code,

auto fin = ifstream("address", ios::binary);
if(fin.is_open()) 
    fin.close()
for(auto i = 0; i < N; ++i){
    fin.open()
    // ....
    // read (next) b bytes...
    // ....
    fin.close()
    // Some delay
}

The code above can't be implemented in the C++ I know, but I'd like to know if it is possible to do so?

Here are my requirements:

Clarification

Upvotes: 1

Views: 3910

Answers (1)

Christophe
Christophe

Reputation: 73542

The need

Indeed, a file can't be deleted by another process as long as a stream keeps it open.

I suppose you have already asked yourself these questions, but fo the recors I have to suggest you to think about it:

  • Can't the file be read into (virtual) memory and discarded when no longer needed ?
  • Can't the file processing be pipelined asynchronously, to read it at once and process it without unnecessary delays ?
  • What to do if the file can no longer be opened because it was deleted by the other process ? What to do if the location can't be found, because the file was modified (e.g. shortened) ?
  • If you would have the perfect solution to your issue, what would be the effect if the other process would try to delete the file when it is open (only for a short time, but nevertheless open and blocking the deletion) ?

The solution

Unfortunately, you can't achieve the desired behavior with standard streams. You could emulate it by keeping track of the filename and of the position (and more generally of the state):

   auto mypos = ifs.tellg();  // saves position.  
                              // Should flag be saved as well ? and what about gcount ?
   ifs.close();  

   ...

   if (! ifs.is_open()) {
       ifs.open(myfilename, myflags);  // open again !  
       if (! ifs) { 
           // ouch ! file disapeared ==> process error 
       }
       ifs.seekg(mypos);              // restore position 
       if (! ifs) { 
           // ouch ! position no longer reachable  ==> process error 
       }
   }

Of course, you wouldn't like to repeat this code ever and ever. And it would not be so nice having all the sudden a lot of global variables to keep track of the stream's state. But you could very easily encapsulate it in a wrapper class that would take care of saving and restoring the stream's state using existing standard operations.

Upvotes: 2

Related Questions