Problem mixing read and write on io fstream

S

Sachin Garg

I have a program which opens a fstream in binary input+output mode, creating
the file if it doesn't exists. But writing doesn't works after reading, it
must be something obvious that I am not aware of.

f.open(filename,ios::in | ios::eek:ut | ios::binary | ios::trunc)

The program flow is

1) write some data
2) read the data
3) overwrite old data //this fails

I am aware that mixing reading and writting is complicated due to buffering
and as far as I know the solution is to do a seekg or seekp when changing
between reading and writting, I am doing this between 1, 2 and 3.

In 'my' program, writting in step 3 fails. I wrote a simple program that
does just the above 3 steps with seeks and it works but in my program, it
sets the failbit.

After lots of debugging in internal fstream code I figured that an internal
flag _IOREAD gets set somehow in step 2 which indicates that the stream is
now readonly and causes subsequent writes to fail. It also seems that
_IOREAD is set anytime any read operation is done on a read+write file, is
this correct? And now how do I 'unset' this flag? I tried calling f.clear
and f.seekp but that doesnt helps.

What might be special in my program that causes this read-mode flag to
remain set while this doesn't happens in a barebone/simple test program. I
am not doing anything except f.seekg, f.get, f.read.

Sachin Garg

ps. If it matters, I am using visual studio 9.0
 
R

Ron AF Greve

Hi,



This is how I read/write to the same file (my virtual file system :) ):

BTW I open the file as follows:

File = new fstream( Filename.c_str(), ios_base::in | ios_base::eek:ut |
ios_base::binary );

and the just seekg and seekp and read or write resp.



void VResLocationManager::Store( VResLocation& Location, const std::string&
Data )
{
unsigned long TotalSize = static_cast<unsigned long>( Data.size() ) +
sizeof( unsigned long );
if( TotalSize > Location.GetSize() )
{
DeleteLocation( Location );
NewLocation( Location, TotalSize );
}

fstream *File = FileSystems[ Location.GetFileNr() ]->File;
Channel << Level4 << " Offset = " << Location.GetOffset() << " Slot Size =
" << Location.GetSize() << " Data Size = " << TotalSize << " Data checksum
= " << CheckSum( Data ) << End;

File->seekp( Location.GetOffset(), ios_base::beg );

File->write( reinterpret_cast<char*>( &TotalSize ), sizeof( TotalSize ) );
if( Data.size() )
{
File->write( &Data[ 0 ], static_cast<unsigned long>( Data.size() ) );
}

}

void VResLocationManager::Retrieve( VResLocation& Location, std::string&
Data )
{
fstream *File = FileSystems[ Location.GetFileNr() ]->File;

File->seekg( Location.GetOffset(), ios_base::beg );

unsigned long TotalSize = 0;
File->read( reinterpret_cast<char*>( &TotalSize ), sizeof( TotalSize ) );

Data.resize( TotalSize - sizeof( unsigned long ) );
if( TotalSize ) File->read( &Data[ 0 ], static_cast<unsigned long>(
Data.size() ) );

// Channel << Level4 << "Retrieved Offset = " << Location.GetOffset() <<
" Slot Size = " << Location.GetSize() << " Data Size = " << TotalSize << "
Data checksum = " << CheckSum( Data ) << End;;
}

Regards, Ron AF Greve

http://www.InformationSuperHighway.eu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top