2009-10-28 43 views
49

Estoy construyendo una aplicación (en Windows usando Dev-C++) y quiero que descargue un archivo. Estoy haciendo esto usando libcurl (ya he instalado el código fuente usando Packman). Encontré un ejemplo de trabajo (http://siddhantahuja.wordpress.com/2009/04/12/how-to-download-a-file-from-a-url-and-save-onto-local-directory-in-c-using-libcurl/) pero no cierra el archivo después de que se completa la descarga. Me gustaría que alguien diera un ejemplo sobre cómo descargar un archivo, ya sea en c o C++. ¡Gracias por adelantado!Descargar archivo usando libcurl en C/C++

+6

que querían votar a su pregunta, pero su respuesta me hizo para no hacerlo. –

Respuesta

179

El ejemplo que está utilizando es incorrecto. Consulte la página del manual para easy_setopt. En el ejemplo, write_data usa su propio ARCHIVO, * archivo de salida, y no el fp que se especificó en CURLOPT_WRITEDATA. Es por eso que cerrar fp causa problemas, ni siquiera se abre.

Esto es más o menos lo que debe ser similar (sin libcurl disponible aquí para probar)

#include <stdio.h> 
#include <curl/curl.h> 
/* For older cURL versions you will also need 
#include <curl/types.h> 
#include <curl/easy.h> 
*/ 
#include <string> 

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) { 
    size_t written = fwrite(ptr, size, nmemb, stream); 
    return written; 
} 

int main(void) { 
    CURL *curl; 
    FILE *fp; 
    CURLcode res; 
    char *url = "http://localhost/aaa.txt"; 
    char outfilename[FILENAME_MAX] = "C:\\bbb.txt"; 
    curl = curl_easy_init(); 
    if (curl) { 
     fp = fopen(outfilename,"wb"); 
     curl_easy_setopt(curl, CURLOPT_URL, url); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 
     res = curl_easy_perform(curl); 
     /* always cleanup */ 
     curl_easy_cleanup(curl); 
     fclose(fp); 
    } 
    return 0; 
} 

Actualizado: como sugiere @rsethc types.h y easy.h no están presentes en las versiones actuales de cURL nunca más.

+1

He intentado esto (en OSX), pero me estoy haciendo: advertencia: desaprobado conversión de constante a 'char *' símbolos no definidos cadena: "___gxx_personality_v0", hace referencia a partir de: _main en ccHRyU1T.o write_data (void *, unsigned long, unsigned long, __sFILE *) en ccHRyU1T.o CIE en ccHRyU1T.o ld: símbolo (s) no encontrado collect2: ld returned 1 estado de salida Help please !! – TCB13

+0

@ TCB13 el programa que escribí es C, no C++. Vuelva a compilar como C y los problemas deberían desaparecer. – fvu

+8

+1 porque creo que el OP debería haber seleccionado esto como la respuesta, porque el código es prácticamente el mismo. – alexy13

14

Solo para los interesados ​​puede evitar escribir una función personalizada pasando NULL como último parámetro (si no tiene la intención de hacer un procesamiento adicional de los datos devueltos).
En este caso, se utiliza la función interna predeterminada.

detalles
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTWRITEDATA

Ejemplo

#include <stdio.h> 
#include <curl/curl.h> 

int main(void) 
{ 
    CURL *curl; 
    FILE *fp; 
    CURLcode res; 
    char *url = "http://stackoverflow.com"; 
    char outfilename[FILENAME_MAX] = "page.html"; 
    curl = curl_easy_init();                                                               
    if (curl) 
    { 
     fp = fopen(outfilename,"wb"); 
     curl_easy_setopt(curl, CURLOPT_URL, url); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 
     res = curl_easy_perform(curl); 
     curl_easy_cleanup(curl); 
     fclose(fp); 
    } 
    return 0; 
} 
+0

Esto no funciona en Windows. En Windows debe configurar CURLOPT_WRITEFUNCTION no nulo; de lo contrario, se produce un bloqueo. Ver https://curl.haxx.se/libcurl/c/CURLOPT_WRITEDATA.html –

+0

@PhilRosenberg Bueno, esto suena desafortunado, ya que aquí https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html # DESCRIPTION indica claramente: "Establezca esta opción en NULL para obtener la función predeterminada interna utilizada en lugar de su devolución de llamada". Por lo tanto, esto "Si está utilizando libcurl como una DLL win32, DEBE usar la CURLOPT_WRITEFUNCTION si establece esta opción o experimentarás caídas ". no debería tener ningún efecto, ya que nuevamente se debería usar la función interna. – Petar