Connecting Tech Pros Worldwide Forums | Help | Site Map

Problem mixing read and write on io fstream

Sachin Garg
Guest
 
Posts: n/a
#1: Aug 22 '08

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



Ron AF Greve
Guest
 
Posts: n/a
#2: Aug 22 '08

re: Problem mixing read and write on io fstream


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" <sachingarg@c10n.infowrote in message
news:g8mcgp$lur$1@aioe.org...
Quote:
>
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
>
>

Closed Thread