2017-04-23 1 views
1

J'utilise le type filetering_istream pour enregistrer les informations dans un fichier décompressé en utilisant 'boost/iostreams/filtering_stream.hpp'. Mais je veux le lancer dans le type ifstream. Y at-il un moyen de le faire? Grand merci!Convertit une variable de type filtering_istream en type ifstream?

Le code est le suivant:

#include <istream> 
#include <fstream> 
#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/filter/gzip.hpp> 

int main(){  
    std::ifstream file("test_data.dat.gz"); 

    boost::iostreams::filtering_istream in; 

    in.push(boost::iostreams::gzip_decompressor()); 

    in.push(file); 

    /* add code to convert filtering_istream 'in' into ifstream 'pfile' */ 

    /* It seems that the following code returns a pointer NULL */ 

    // std::ifstream* pfile = in.component<std::ifstream>(1); 

    return 0; 

} 

Après avoir essayé boost :: ref et boost :: emballage proposé par zett42, le ifstream fonctionne vraiment. Le seul problème est qu'il ne donne pas les phrases voulues.

Dans mon texte de fichier .gz, j'ai écrit:

THIS IS A DATA FILE! 
8 plus 8 is 16 

Mais en utilisant le ifstream, je me suis:

is_open: 1 

\213<\373Xtest_data.dat\361\360V"G\307G7OWE.\205\202\234\322b\205\314bC3.\327+>\314$

Je ne sais pas ce qui est arrivé ici, et puis-je faire quelque chose pour le récupérer?

+0

Si vous utilisez 'ifstream', vous lirez les données * compressées *. Peut-être que j'ai mal compris votre problème complètement. Si vous voulez lire les données non compressées, vous lisez simplement 'in'. Pas besoin de "jeter" quoi que ce soit alors. – zett42

Répondre

0

De la référence de filtering_stream:

filtering_stream dérive de std :: basic_istream, std :: basic_ostream ou std :: basic_iostream, en fonction de son paramètre de mode.

pas Donc, vous ne pouvez pas lancer un filtering_stream directement à un ifstream parce qu'il n'y a pas de relation d'héritage entre les deux. Ce que vous pouvez faire à la place, si votre chaîne de filtre se termine par un ifstream, vous pouvez grap cet appareil en appelant filtering_stream::component(). Pour les flux, cette fonction renvoie un boost::iostreams::detail::mode_adapter (vous pouvez voir le type en appelant in.component_type(1)). Il n'est probablement pas une bonne idée de dépendre d'un type de boost interne (indiqué par l'espace de nommage "detail") qui pourrait changer avec la prochaine version boost, donc une solution consiste à utiliser boost::reference_wrapper à la place.

#include <iostream> 
#include <istream> 
#include <fstream> 
#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/filter/gzip.hpp> 
#include <boost/core/ref.hpp> 

int main(){  
    std::ifstream file("test_data.dat.gz"); 

    boost::iostreams::filtering_istream in; 

    in.push(boost::iostreams::gzip_decompressor()); 

    in.push(boost::ref(file)); 

    if(auto pfile = in.component<boost::reference_wrapper<std::ifstream>>(1)) 
    { 
     std::ifstream& rfile = *pfile; 
     std::cout << "is_open: " << rfile.is_open() << "\n"; 
    } 
} 
+0

Thx pour cette inspiration, mais il semble que pfile est un pointeur NULL, provoquant une erreur de segmentation si je veux imprimer le contenu à l'intérieur. Avez-vous une idée à ce sujet? Je suis sûr que le 'in' est correct, parce que je peux sortir le contenu Inside en utilisant la fonction getline. Grand merci! – hyoukai

+0

@hyoukai Pourriez-vous ajouter un échantillon de code à votre question? – zett42

+0

Merci pour votre attention. Le code a été ajouté. Great thx si vous pouvez me proposer quelques idées! – hyoukai