By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,617 Members | 1,591 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,617 IT Pros & Developers. It's quick & easy.

Problem mixing read and write on io fstream

P: n/a

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::out | 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
Aug 22 '08 #1
Share this Question
Share on Google+
1 Reply


P: n/a
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::out |
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

"Sachin Garg" <sa********@c10n.infowrote in message
news:g8**********@aioe.org...
>
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::out | 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


Aug 22 '08 #2

This discussion thread is closed

Replies have been disabled for this discussion.