====== Scaricare un file dal web con LibCurl ====== Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **//14/02/2011//** \\ \\ Con [[http://curl.haxx.se/libcurl/|libCurl]] e' possibile scaricare e caricare file in [[http://curl.haxx.se/docs/features.html|molti tipi di server]] semplicemente specificando la Url. \\ Di seguito un'esempio ben commentato mostrera' come scaricare un file dal web.L'esempio in questione, volutamente semplice, ha l'intenzione di far comprendere velocemente l'utilizzo di base di libcurl . \\ Altri esempi piĆ¹ complessi possono essere scaricati da questa pagina: [[http://curl.haxx.se/libcurl/c/example.html|http://curl.haxx.se/libcurl/c/example.html]] ===== Scaricare un file dal web ===== **main.c** \\ \\ #include #include /* Link utili: * http://curl.haxx.se/libcurl/c/example.html */ /* Questa funzione e' opzionale per quello che faremo noi, e' una callback * che se si vuole si puo' attivare non appena riceviamo i dati, per svolgere su * essi qualsiasi compito.*/ static size_t callback(void *buffer, size_t size, size_t nmemb, void *stream); int main(void) { CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl) { /*Settiamo la URL del nostro file*/ curl_easy_setopt(curl, CURLOPT_URL, "http://www.google.it/search?hl=it&q=ciao&btnG=Cerca+con+Google"); /* Opzionale - Colleghiamo la funzione "callback" * questa funzione viene eseguita non appena viene invocato curl_easy_perform()*/ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); /* Apriamo un file che conterra la nostra pagina scaricata * potrebbe anche essere un altro tipo di file.*/ FILE *f = fopen("file.html","w"); if (f == NULL) { curl_easy_cleanup(curl); return -1; } /* Con questa istruzione scriviamo i dati catturati dall'url nel file f */ curl_easy_setopt(curl,CURLOPT_WRITEDATA, f); /* Esegue tutte le istruzioni che abbiam dati fin ora, res conterra * il codice d'errore */ res = curl_easy_perform(curl); /* Pulisce il nostro handle */ curl_easy_cleanup(curl); fclose(f); } return 0; } size_t callback(void *buffer, size_t size, size_t nmemb, void *stream){ int written = fwrite(buffer, size, nmemb, (FILE *)stream); /* Questa callback viene attivata non appena viene conclusa * curl_easy_perform(), non serve a nulla e' solo dimostrativa. * Puo' svolgere qualsiasi compito sui dati catturati dall URL . * La variabile buffer contiene i dati catturati. */ return written; } ===== Il makefile ===== I nostri progetti possono essere linkati a libcurl sia in maniera statica che dinamica, passando adeguatamente i parametri al programma ''curl-config'' . \\ Da notare infatti che cambia soltanto la seconda riga, infatti ''OPTS = `curl-config --static-libs`'' e invece ''OPTS = `curl-config --cflags --libs` '' per la compilazione dinamica ==== Makefile per link statico ==== CPP = gcc OPTS = `curl-config --static-libs` all: $(CPP) main.c -o main $(OPTS) clean: rm main ==== Makefile per link dinamico ==== CPP = gcc OPTS = `curl-config --cflags --libs` all: $(CPP) main.c -o main $(OPTS) clean: rm main ===== Mostrare l'avanzamento del download ===== Per arricchire il nostro esempio potremmo fare in modo da mostrare l'avanzamento del download tramite la nostra callback **int progress( void* ptr, double t, double d, ouble ultotal,double ulnow); ** in questo modo: #include #include static size_t writecallback(void *buffer, size_t size, size_t nmemb, void *stream); int progress( void* ptr, double t, /* dltotal */ double d, /* dlnow */ double ultotal, double ulnow); int main(void) { CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl) { /*Settiamo la URL del nostro file*/ curl_easy_setopt(curl, CURLOPT_URL, "http://gapil.truelite.it/gapil.pdf"); /* Apriamo un file che conterra la nostra pagina scaricata */ FILE *f = fopen("file.pdf","w"); if (f == NULL) { curl_easy_cleanup(curl); return -1; } /* Con questa istruzione scriviamo i dati catturati dall'url nel file f */ curl_easy_setopt(curl,CURLOPT_WRITEDATA, f); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecallback); /*Per l'avanzamento dello stato del dowload*/ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress); /* Esegue tutte le istruzioni che abbiam dati fin ora, res conterra * il codice d'errore */ res = curl_easy_perform(curl); /* Pulisce il nostro handle */ curl_easy_cleanup(curl); fclose(f); } return 0; } size_t writecallback(void *buffer, size_t size, size_t nmemb, void *stream){ int written = fwrite(buffer, size, nmemb, (FILE *)stream); return written; } int progress( void* ptr, double t, /* dltotal */ double d, /* dlnow */ double ultotal, double ulnow) { /*Progresso in Kilobyte*/ //printf("Dl->%4.2f kb di %d kb\n",d/1024, (int)t/1024); /*Progresso in percentuale*/ double percento= d*100/t; printf("Scaricato il %d% \n", (int)percento); return 0; }