Problem mixing read and write on io fstream

Discussion in 'C++' started by Sachin Garg, Aug 22, 2008.

  1. Sachin Garg

    Sachin Garg Guest

    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
    Sachin Garg, Aug 22, 2008
    #1
    1. Advertising

  2. Sachin Garg

    Ron AF Greve Guest

    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

    "Sachin Garg" <> wrote in message
    news:g8mcgp$lur$...
    >
    > 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
    >
    >
    Ron AF Greve, Aug 22, 2008
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Armando
    Replies:
    6
    Views:
    730
    Armando
    Jan 29, 2004
  2. Jon Hyland
    Replies:
    4
    Views:
    6,070
    Jon Hyland
    Oct 5, 2004
  3. Jon Slaughter

    Replace write in fstream

    Jon Slaughter, Dec 29, 2004, in forum: C++
    Replies:
    6
    Views:
    2,559
    Jon Slaughter
    Dec 29, 2004
  4. Replies:
    2
    Views:
    1,133
    Abecedarian
    May 12, 2005
  5. ZikO
    Replies:
    3
    Views:
    6,248
    James Kanze
    Feb 5, 2009
Loading...

Share This Page