Libcurl: image在使用fstream::write而不是fwrite时被损坏
Libcurl: image is damaged when using fstream::write instead of fwrite
我正在尝试从url下载图像文件。我以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 successfullyn" << 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
。"
……那么size和nmemb的含义是什么呢?
当尝试从网站下载数据时,我打印了前3个参数。似乎char*ptr
是数据存储的内存地址(作为'char a[]'?), size
是元素的大小,nmemb是元素的数量。所以数据大小= size * 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'来获得数据内存的大小,以便我可以证明数据大小是'size * 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;
}
谢谢!:)
每个文件可以多次回调。你不应该在每次函数被调用时都创建一个新的文件流——你应该使用user data参数传递它。否则,您将继续覆盖文件开头的数据。
下面是一个示例实现:
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;
}
您还需要使用参数CURLOPT_WRITEDATA
调整对curl_easy_setopt
的调用,以便实际传递文件流。确保流在函数运行时不会超出作用域!
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;
}
}
相关文章:
- 为什么会发生堆损坏
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 平均图像时图像损坏
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 为什么C中的通用链表中存储的数据已损坏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- C++双重释放或损坏(out)
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 使用全局声明的向量时,C++双重释放错误/损坏
- 变量周围的堆栈'...'已损坏
- 运行时检查失败 #2 变量"A"周围的堆栈已损坏
- 检测到堆损坏:在正常块 c++ 动态 2D 数组之后
- 删除字符串后C++检测到堆损坏
- 两个垫子的 OpenCV 数据是相同的,但使用 Mat::at 检索时的值已损坏
- 我可以写入关闭的套接字并强制纠正损坏的管道错误吗?
- 损坏的结构字符数组 - sqlite C++
- C++fwrite会损坏二进制文件
- 在大文件上使用fwrite导致字节损坏
- fwrite()文件损坏c++
- Libcurl: image在使用fstream::write而不是fwrite时被损坏