2010-11-23 9 views
5

मैं अपने सी ++ प्रोग्राम में libcurl के साथ एक फ़ाइल डाउनलोड कर रहा हूं। मैं कैसे पता लगा सकता हूं कि अनुरोध 404 है, और फ़ाइल लिखना नहीं है? कोड है:libcurl 404 पहचान

void GameImage::DownloadImage(string file_name) { 
    string game_name; 
    game_name = file_name.substr(file_name.find_last_of("/")+1); 

    CURL *curl; 
    FILE *fp; 
    CURLcode res; 
    string url = "http://site/"+game_name+".png"; 
    string outfilename = file_name+".png"; 
    cout<<"INFO; attempting to download "<<url<<"..."<<endl; 
    curl = curl_easy_init(); 
    if (curl) { 
     cout<<"INFO; downloading "<<url<<"..."<<endl; 
     fp = fopen(outfilename.c_str(), "wb"); 
     cout<<"INFO; trying to open "<<outfilename<<" for file output"<<endl; 
     if (fp != NULL) { 
      curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); 
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GameImage::WriteData); 
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 
      curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); 
      curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); 
      res = curl_easy_perform(curl); 

      long http_code = 0; 
      curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); 

      curl_easy_cleanup(curl); 
      fclose(fp); 
     } 
     else { 
      cout<<"GameImage::DownloadImage; Couldn't open output file"<<endl; 
     } 
    } 
} 

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

स्थानांतरण के बाद 404 प्रतिक्रिया हटा दी जा सकती है, लेकिन यह प्रतिक्रिया भी सहेजना अच्छा नहीं होगा।

उत्तर

4

आप के खिलाफ CURLE_HTTP_RETURNED_ERROR

यह CURLOPT_FAILONERRORtrue पर सेट है और HTTP सर्वर एक त्रुटि कोड है कि है >= 400 लौटाता है यदि दिया जाता है देख सकते हैं। आप विशिष्ट HTTP प्रतिक्रिया कोड नहीं ले सकते हैं, लेकिन जो भी आप चाहते हैं उसे पूरा करने के लिए पर्याप्त होना चाहिए।

+0

मुझे अभी भी एक फ़ाइल मिलती है, लेकिन अब यह खाली है। मैंने curl_easy_setopt जोड़ा (कर्ल, CURLOPT_FAILONERROR, सच); मुझे कोई परवाह नहीं है कि एक त्रुटि हुई, मैं नहीं चाहता कि फ़ाइल पीछे छोड़ी जाए। – zombor

+0

क्या आप अपने प्रश्न के साथ अपना प्रश्न अपडेट कर सकते हैं? – Alex

+0

हो गया। मुझे लगता है कि यह प्रारंभिक fp = fopen (outfilename.c_str(), "wb") की वजह से है; जो फाइल हैंडल बनाता है। – zombor

1

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन आप जो त्रुटि कर रहे हैं वह यह है कि आप curl_easy_perform के वापसी मूल्य की जांच नहीं कर रहे हैं। CURLOPT_FAILONERROR सेट करना प्रोग्राम को क्रैश नहीं करेगा, इसके बजाय, यह आपके द्वारा नामित रिटर्न वैरिएबल के माध्यम से त्रुटि के बारे में सूचित करेगा। खाली फ़ाइल से छुटकारा पाने के लिए, आप ऐसा कुछ कर सकते हैं:

void GameImage::DownloadImage(string file_name) { 
    string game_name; 
    game_name = file_name.substr(file_name.find_last_of("/")+1); 

    CURL *curl; 
    FILE *fp; 
    CURLcode res; 
    string url = "http://site/"+game_name+".png"; 
    string outfilename = file_name+".png"; 
    cout<<"INFO; attempting to download "<<url<<"..."<<endl; 
    curl = curl_easy_init(); 
    if (curl) { 
     cout<<"INFO; downloading "<<url<<"..."<<endl; 
     fp = fopen(outfilename.c_str(), "wb"); 
     cout<<"INFO; trying to open "<<outfilename<<" for file output"<<endl; 
     if (fp == NULL) { 
      cout<<"GameImage::DownloadImage; Couldn't open output file"<<endl; 
      curl_easy_cleanup(curl); 
      return; 
     } 
     curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GameImage::WriteData); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 
     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); 
     curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); 
     res = curl_easy_perform(curl); 
     fclose(fp); 

     if (res != CURLE_OK) { 
      cout<<"GameImage::DownloadImage; Failed to download file"<<endl; 
      remove(outfilename.c_str()); 
     } 

     curl_easy_cleanup(curl); 
    } 
} 

size_t GameImage::WriteData(void *ptr, size_t size, size_t nmemb, FILE *stream) { 
    size_t written; 
    written = fwrite(ptr, size, nmemb, stream); 
    return written; 
} 
संबंधित मुद्दे