Problem mixing read and write on io fstream

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Sachin Garg

    Problem mixing read and write on io fstream


    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

    #2
    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::binar y );

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



    void VResLocationMan ager::Store( VResLocation& Location, const std::string&
    Data )
    {
    unsigned long TotalSize = static_cast<uns igned long>( Data.size() ) +
    sizeof( unsigned long );
    if( TotalSize Location.GetSiz e() )
    {
    DeleteLocation( Location );
    NewLocation( Location, TotalSize );
    }

    fstream *File = FileSystems[ Location.GetFil eNr() ]->File;
    Channel << Level4 << " Offset = " << Location.GetOff set() << " Slot Size =
    " << Location.GetSiz e() << " Data Size = " << TotalSize << " Data checksum
    = " << CheckSum( Data ) << End;

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

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

    }

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

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

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

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

    // Channel << Level4 << "Retrieved Offset = " << Location.GetOff set() <<
    " Slot Size = " << Location.GetSiz e() << " Data Size = " << TotalSize << "
    Data checksum = " << CheckSum( Data ) << End;;
    }

    Regards, Ron AF Greve



    "Sachin Garg" <sachingarg@c10 n.infowrote in message
    news:g8mcgp$lur $1@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
    >
    >

    Comment

    Working...