我试图从网址下载图片文件。我使用fwrite
跟踪了示例,并且成功了。现在,我尝试使用fstream::write
保存数据(ios::binary
),但数据已损坏。这是我的代码:
#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中的参数感到困惑。 根据{{3}}
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
&#34;
ptr
指向已投放的数据,该数据的大小为size
乘以nmemb
。&#34;
......那么尺寸和nmemb的含义是什么?
当试图从网站下载数据时,我打印了前3个参数。 char*ptr
似乎是存储数据的内存地址(&#39; char a []&#39;?),而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
下载相同的网址,文件和文件时开放时间经常变化。
我也对&#39; sizeof(ptr)&#39;感到困惑,它返回&#39; 4&#39;(int的大小?)。我怎样才能使用&#39; sizeof&#39;为了获得数据内存的大小,我可以证明 数据大小是&#39; size * nmemb&#39;
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;
}
谢谢! :)
答案 0 :(得分:1)
每个文件可以多次回调。每次调用函数时都不应创建新的文件流 - 您应该使用用户数据参数传递它。否则,您将继续覆盖文件开头的数据。
以下是一个示例实现:
size_t write_data(char *ptr, size_t size, size_t nmemb, void *userdata)
{
std::ofstream *out = static_cast<std::ofstream *>(userdata);
size_t nbytes = size * nmemb;
out->write(ptr, nbytes);
return nbytes;
}
您还需要使用参数curl_easy_setopt
调整对CURLOPT_WRITEDATA
的调用,以实际传递您的文件流。确保在函数运行时流不会超出范围!
CURLcode download(char* url, char* out) {
CURL *curl = NULL;
std::ofstream output(out, ios::binary);
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, &output);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}
else
{
return CURLE_FAILED_INIT;
}
}