Writing in binary file

Asked

Viewed 303 times

0

How do I write at any position of a binary file using the fstream library without overwriting the content already inserted in the file? I started trying like this:

    ofstream salvar;
    salvar.open(arq_dados,ios::binary);
    salvar.seekp(sizeof(structGenerica) * posicaoArquivo );
    salvar.write((const char*)(&structAux), sizeof(structGenerica));
    salvar.close();

I also tried using the Ios :: app flag that also didn’t work.

  • 1

    What have you tried? It’s a good step for us to understand precisely where your doubt is. In fact, it would just avoid opening the file as written only, maybe what you want is the way to append or read+, which also allows writing

  • the ideal is to edit the question, then at most mark me in the comment for me to see the update.

  • @Jeffersonquesado

  • Possible duplicate of Overwriting records in binary file

  • @Articuno , really ,forgot to delete the other question , thank you

  • @Raphaelroriz keep erasing issues is bad, very bad. Better try to save than create new copies, and the other issue had salvation. Gets the hint

  • @Jeffersonquesado thanks for the tip!

Show 2 more comments

1 answer

0


You are not paying attention to the file opening modes in the constructor call std::ofstream and in the reference position passed as parameter to the method std::ofstream::seekp().

Follows a function capable of writing a "generic" structure into a binary file:

void gravar_arquivo( void * p, std::size_t n, const char * arq, long pos = -1 )
{
    if( pos == -1 )
    {
        // Apenas inclui um novo registro no final do arquivo (append)
        std::ofstream ofs( arq, std::ios::binary | std::ios::out | std::ios::app );
        ofs.write( (char*) p, n );
        ofs.close();
    }
    else
    {
        // Grava em uma posicao especifica do arquivo
        std::ofstream ofs( arq, std::ios::binary| std::ios::out | std::ios::in );
        ofs.seekp( n * pos, std::ios::beg );
        ofs.write( (char*) p, n );
        ofs.close();
    }
}

Program for generating a binary test file called saida.bin containing 5 records:

#include <fstream>
#include <cstring>


typedef struct foobar_s
{
    char id;
    char text[16];
} foobar_t;


void gravar_arquivo( void * p, std::size_t n, const char * arq, long pos = -1 )
{
    if( pos == -1 )
    {
        // Apenas inclui um novo registro no final do arquivo (append)
        std::ofstream ofs( arq, std::ios::binary | std::ios::out | std::ios::app );
        ofs.write( (char*) p, n );
        ofs.close();
    }
    else
    {
        // Grava em uma posicao especifica do arquivo
        std::ofstream ofs( arq, std::ios::binary| std::ios::out | std::ios::in );
        ofs.seekp( n * pos, std::ios::beg );
        ofs.write( (char*) p, n );
        ofs.close();
    }
}


int main( void )
{
    foobar_t fb[5];

    /* Preenche 5 registros */
    fb[0].id = 1; std::strcpy( fb[0].text, "Alpha" );
    fb[1].id = 2; std::strcpy( fb[1].text, "Beta" );
    fb[2].id = 3; std::strcpy( fb[2].text, "Gamma" );
    fb[3].id = 4; std::strcpy( fb[3].text, "Delta" );
    fb[4].id = 5; std::strcpy( fb[4].text, "Episilon" );

    /* Grava sequenciamente os 5 registro em arquivo binario */
    for( int i = 0; i < 5; i++ )
        gravar_arquivo( (void*) &fb[i], sizeof(foobar_t), "saida.bin" );

    return 0;
}

Generated file saida.bin:

0000000: 0141 6c70 6861 0000 2699 33af 4d7f 0000  .Alpha..&.3.M...
0000010: 0102 4265 7461 0000 0000 0000 0000 0000  ..Beta..........
0000020: 0100 0347 616d 6d61 0018 75ae 4d7f 0000  ...Gamma..u.M...
0000030: 0100 0004 4465 6c74 6100 4000 0000 0000  ....Delta.@.....
0000040: 0000 0000 0545 7069 7369 6c6f 6e00 0000  .....Episilon...
0000050: 700b 4000 00                             p.@..

Now, a program capable of changing only the Quarto record contained in the file saida.bin:

#include <fstream>
#include <cstring>


typedef struct foobar_s
{
    char id;
    char text[16];
} foobar_t;


void gravar_arquivo( void * p, std::size_t n, const char * arq, long pos = -1 )
{
    if( pos == -1 )
    {
        // Apenas inclui um novo registro no final do arquivo (append)
        std::ofstream ofs( arq, std::ios::binary | std::ios::out | std::ios::app );
        ofs.write( (char*) p, n );
        ofs.close();
    }
    else
    {
        // Grava em uma posicao especifica do arquivo
        std::ofstream ofs( arq, std::ios::binary| std::ios::out | std::ios::in );
        ofs.seekp( n * pos, std::ios::beg );
        ofs.write( (char*) p, n );
        ofs.close();
    }
}


int main( void )
{
    foobar_t fb;

    fb.id = 99;
    std::strcpy( fb.text, "Omega" );

    gravar_arquivo( (void*) &fb, sizeof(foobar_t), "saida.bin", 3 );

    return 0;
}

Filing cabinet modified saida.bin:

0000000: 0141 6c70 6861 0000 2699 33af 4d7f 0000  .Alpha..&.3.M...
0000010: 0102 4265 7461 0000 0000 0000 0000 0000  ..Beta..........
0000020: 0100 0347 616d 6d61 0018 75ae 4d7f 0000  ...Gamma..u.M...
0000030: 0100 0063 4f6d 6567 6100 0000 0840 0000  ...cOmega....@..
0000040: 0000 00c0 0545 7069 7369 6c6f 6e00 0000  .....Episilon...
0000050: 700b 4000 00                             p.@..

Browser other questions tagged

You are not signed in. Login or sign up in order to post.