Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: Piotr Szawdyński
Inne artykuły

Jak korzystać z boost::archive::binary_oarchive

[artykuł] Artykuł zawiera przykład użycia boost::archive::binary_oarchive oraz boost::archive::binary_iarchive.
Pisząc większe programy w C++ bardzo często wykorzystujemy bibliotekę boost. Używanie tej biblioteki w większości przypadków sprowadza się do narzędzi, które znają wszyscy programiści korzystający z boost-a np. do szablonu shared_ptr. Należy jednak pamiętać, że boost dostarcza nam wiele narzędzi o szerokim zastosowaniu, a więc warto poświęcać czas na ich poznawanie.

W niniejszym artykule przedstawię praktyczny kod do serializacji danych do postaci binarnej oraz mechanizm umożliwiający ich deserializację. To wszystko osiągniemy przy pomocy narzędzi dostępnych w bibliotece boost, a dokładniej przy pomocy klas boost::archive::binary_oarchive oraz boost::archive::binary_iarchive. Sposób korzystania ze wspomnianych narzędzi został ujęty w postaci krótkiego kodu, który serializuje oraz deserializuje zmienne różnych typów.

Przykład

C/C++
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <vector>
#include <cstdio>
#include <sstream>

void serialize( std::vector < char >& result )
{
    std::stringstream dane;
    boost::archive::binary_oarchive bin( dane );
   
    std::string bla = "to jest napis.";
    bin << bla;
    bin << "to jest napis.";
    bin << "\0";
    int liczba = 54321;
    double abc = 1234.5678;
    bin & liczba;
    bin & abc;
    bin & "zz";
   
    result.clear();
    for( char c = dane.get(); dane.good(); c = dane.get() )
         result.push_back( c );
   
}

void deserialize( const std::vector < char >& result )
{
    std::stringstream dane;
    dane.write( & result[ 0 ], result.size() );
    boost::archive::binary_iarchive bin( dane );
    std::string napis;
    bin >> napis;
    printf( "deserialize (%d) = %s\n", napis.size(), napis.c_str() );
    bin >> napis;
    printf( "deserialize (%d) = %s\n", napis.size(), napis.c_str() );
    bin >> napis;
    printf( "deserialize (%d) = %s\n", napis.size(), napis.c_str() );
    int liczba;
    bin & liczba;
    printf( "deserialize = %d\n", liczba );
    double abc;
    bin & abc;
    printf( "deserialize = %Lf\n", abc );
    bin & napis;
    printf( "deserialize (%d) = %s\n", napis.size(), napis.c_str() );
}

void outputBinary( const std::vector < char >& result )
{
    for( size_t i = 0; i < result.size(); ++i )
         printf( "%02x",( const int ) static_cast < const unsigned char >( result[ i ] ) );
   
    printf( "\n" );
}

int main()
{
    std::vector < char > result;
    serialize( result );
    outputBinary( result );
    deserialize( result );
    return 0;
}
Standardowe wyjście programu:
1600000073657269616c697a6174696f6e3a3a61726368697665090004040408010000000e000000
746f206a657374206e617069732e0f000000746f206a657374206e617069732e0002000000000031
d40000adfa5c6d454a9340030000007a7a00
deserialize (14) = to jest napis.
deserialize (15) = to jest napis.
deserialize (2) =
deserialize = 54321
deserialize = 1234.567800
deserialize (3) = zz

Obsługa błędów

Należy pamiętać aby zabezpieczyć swój kod na okoliczność pojawienia się wyjątków. Do tego celu służą oczywiście instrukcje try oraz catch:
C/C++
try
{
    //Tu instrukcje operujące na boost::archive::binary_oarchive
    //lub boost::archive::binary_iarchive
} catch( const std::exception & )
{
    //Tu obsługa wystąpienia błędu
}