Я пытаюсь загрузить файл изображения с URL-адреса. Я следовал примеру, используя fwrite
, и это удалось. Сейчас я пытаюсь использовать fstream::write
, чтобы сохранить данные (ios::binary
), но данные повреждены. Вот мой код:Libcurl: изображение повреждено при использовании fstream :: write вместо fwrite
#include"stdafx.h"
#include<fstream>
#include<iostream>
#include <curl/curl.h>
#include <string.h>
using namespace std;
size_t write_data(void *ptr, size_t size, size_t nmemb, char* out) {
//void *ptr, size_t size, size_t nmemb, File* fp
fstream file;
if (file.is_open()){
file.close();
file.clear();
}
file.open(out, ios::out | ios::binary);
if (file.is_open()){
cout << "open successfully\n" << endl;
file.write((char*)ptr, nmemb*size); // Does it correct?
};
// fwrite(ptr,size,nmemb,fp);
file.close();
file.clear();
cout <<"\n sizeof(ptr): " << sizeof(ptr) //size of ptr[0]?
<<"\n sizeof(char): " << sizeof(char)
<<"\n size: " << size
<<"\n nmemb: " << nmemb<< endl;
return size*nmemb;
}
Я смущен параметрами в write_data. Согласно CURLOPT_WRITEFUNCTION
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
"
ptr
указывает на доставленных данных, и размер этих данныхsize
умножается наnmemb
."
...... так какие значения имеют размер и nmemb?
При попытке загрузить данные с веб-сайта я напечатал первые 3 параметра. Кажется, что char*ptr
является адресом памяти, который хранит данные (как «char a [] '?), А size
- это размер элемента, nmemb - это количество элементов. Таким образом, размер данных = размер * nmemb. Я прав?
Выход путает также:
open successfully
sizeof(ptr):4
sizeof(char):1
size:1
nmemb:2715
open successfully
sizeof(ptr):4
sizeof(char):1
size:1
nmemb:4865
download successfully
Когда скачать тот же URL, nmemb и открытые времена файлов которых часто меняются.
Я также смущен о 'sizeof (ptr)', он возвращает '4' (размер int?). Как я могу использовать 'sizeof' для получения размера памяти данных, чтобы я мог доказательство, что размер данных «размер * nmemb»?
CURLcode download(char* url,char* out){
CURL *curl = NULL;
//FILE *fp = NULL;
CURLcode res;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, out); //fp
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}
else
{
return CURLE_FAILED_INIT;
}
}
int main()
{
CURLcode res = download("http://XXXXXX.gif", "D:\\test.gif");
if (CURLE_OK == res)
cout << "download successfully.\n" << endl;
else
cout<<"cannot download.\n"<<endl;
return 0;
}
Спасибо! :)
В случае, если вы не заметили, ваша функция записи для вашего первого списка кодов всегда записывает свои данные в * начало * файла. Если ваша функция не вызывается только один раз, я не удивлюсь, что она не совпадает с завихрением для файла IO для вас. – WhozCraig
Есть еще одна вещь, которую я заметил. Вы создаете 'fstream', который затем используется только для записи. Как насчет использования 'ofstream' вместо этого, который статически (т. Е. Во время компиляции) позволяет вам использовать его только для этого? Кроме того, вы проверяете, открыт ли поток, что совершенно невозможно! Просто используйте 'outstream-файл (out, ios_base :: binary);'.Позже вы явно закрываете() 'it и' clear() 'streamstate, что избыточно, потому что после этого вы не используете поток. Вместо этого, 'flush()' поток, а затем проверить streamstate для проверки ошибок. Все это не объясняет ваши проблемы. –
Кстати, само определение 'sizeof' заключается в том, что он возвращает размер в кратных символах' char', поэтому этим определением 'sizeof (char)' является ровно один. Всегда. –