Writing in binary file

0

How do I write to 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 did not work either.

    
asked by anonymous 05.06.2018 / 00:55

1 answer

0

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

Here is a function that can write a "generic" structure to 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 test binary file named saida.bin containing 5 registrations:

#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 that can only change the Quarto log 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;
}

modified 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 0063 4f6d 6567 6100 0000 0840 0000  ...cOmega....@..
0000040: 0000 00c0 0545 7069 7369 6c6f 6e00 0000  .....Episilon...
0000050: 700b 4000 00                             p.@..
    
05.06.2018 / 22:00