2010-06-11 9 views
3

Je voudrais utiliser la bibliothèque libcurl pour ouvrir un fichier de date distant et parcourir avec un istream. J'ai regardé à travers le bon exemple dans ce thread mais il écrit le fichier distant dans un fichier local. Au lieu de cela, j'aimerais que les lectures à distance soient poussées vers un istream pour une manipulation programmatique ultérieure. Est-ce possible? J'apprécierais grandement l'aide.Peut-on lire un fichier distant en tant qu'istream avec libcurl?

Best, Aaron

+1

Je ne sais pas à propos de libcurl, mais qu'en est-il de ASIO? –

+0

@anybody +1 car ASIO a exactement cela (flux), mais il n'implémente pas de protocole lui-même (HTTP, FTP, etc) que curl fait. – Gianni

Répondre

2

Boost's IO Stream pourrait être une meilleure solution que propre flux de STL. Au moins, il est beaucoup plus simple de créer un flux boost. De propres docs Boost:

#include <curl/curl.h> 
#include <boost/iostreams/stream.hpp> 

class CURLDevice 
{ 
    private: 
     CURL* handle; 
    public: 
     typedef char       char_type; 
     typedef boost::iostreams::source_tag category; 

     CURLDevice() 
     { 
      handle = curl_easy_init(); 
     } 

     CURLDevice(const std::string &url) 
     { 
      handle = curl_easy_init(); 
      open(url); 
     } 

     ~CURLDevice() 
     { 
      curl_easy_cleanup(handle); 
     } 

     void open(const std::string &url) 
     { 
      curl_easy_setopt(handle, CURLOPT_URL, url.c_str()); 
      curl_easy_setopt(handle, CURLOPT_CONNECT_ONLY, 1); 
      curl_easy_perform(handle); 
     } 

     std::streamsize read(char* s, std::streamsize n) 
     { 
      size_t read; 
      CURLcode ret = curl_easy_recv(handle, s, n, &read); 
      if (ret == CURLE_OK || ret == CURLE_AGAIN) 
       return read; 
      else 
       return -1; 
     } 
}; 

typedef boost::iostreams::stream<CURLDevice> CURLStream; 

int main(int argc, char **argv) 
{ 
    curl_global_init(CURL_GLOBAL_ALL); 

    { 
     CURLStream stream("http://google.com"); 

     char buffer[256]; 
     int sz; 

     do 
     { 
      sz = 256; 
      stream.read(buffer, sz); 
      sz = stream.gcount(); 
      std::cout.write(buffer, sz); 
     } 
     while(sz > 0); 
    } 

    curl_global_cleanup(); 

    return 0; 
} 

Remarque: lorsque je lance le code ci-dessus je reçois une erreur de segmentation dans CURL, cela semble être parce que je ne sais pas exactement comment utiliser se pelotonner.

+0

Merci Gianni. Je ne suis pas familier avec boost iostreams. Pourriez-vous élaborer l'exemple pour montrer comment cela interagirait avec un accès à un fichier distant libcurl et l'utilisation subséquente du flux boost pour la lecture programmée? – jobu