从 libcurl 下载后 mp3 文件损坏
mp3 file corrupted after downloading it from libcurl
我正在使用 libcurl 访问 IBM Watson API,我正在下载 mp3 文件,但下载的文件已损坏。我期待 "hello world" 消息,但相反,我收到了损坏的 mp3 文件或地狱般的声音。我猜错误是在我将响应转换为 const char *
时出现的,它丢失了数据,因为我正在编写二进制数据,而 C++ 认为 null
关键字是字符串结尾。它输出两个不同的字符串。有什么解决办法吗?
代码:
#include <iostream>
#include <fstream>
#include <string>
#include <curl/curl.h>
size_t CurlWrite_CallbackFunc_StdString(void *contents, size_t size, size_t nmemb, std::string *s)
{
size_t newLength = size * nmemb;
try
{
s->append((char*)contents, newLength);
}
catch (std::bad_alloc &e)
{
return 0;
}
return newLength;
}
std::string CurlGetResponse(std::string url) {
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
std::string response;
if (curl)
{
curl_easy_setopt(curl, CURLOPT_USERNAME, "apikey");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "API Key");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //only for https
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); //only for https
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
return response;
}
int main()
{
std::string response = CurlGetResponse("url");
std::cout << response.data();
std::cout << response;
std::fstream file;
file.open("C:\Users\maste\HelloWorld_1.mp3", std::ios::binary);
file.write(response, sizeof(response));
file.close();
return 0;
}
声明
file.write(response, sizeof(response));
包含两个错误:
首先,它将 std::string
对象作为参数传递,但 write
需要一个指向要写入的字节的指针。你需要通过例如response.data()
.
第二个问题(我在评论中也提到了)是sizeof(response)
是std::string
对象本身的大小,而不是它包含的字符串。您需要使用 response.size()
来获取实际字符串的大小。
总而言之,声明应如下所示:
file.write(response.data(), response.size());
我正在使用 libcurl 访问 IBM Watson API,我正在下载 mp3 文件,但下载的文件已损坏。我期待 "hello world" 消息,但相反,我收到了损坏的 mp3 文件或地狱般的声音。我猜错误是在我将响应转换为 const char *
时出现的,它丢失了数据,因为我正在编写二进制数据,而 C++ 认为 null
关键字是字符串结尾。它输出两个不同的字符串。有什么解决办法吗?
代码:
#include <iostream>
#include <fstream>
#include <string>
#include <curl/curl.h>
size_t CurlWrite_CallbackFunc_StdString(void *contents, size_t size, size_t nmemb, std::string *s)
{
size_t newLength = size * nmemb;
try
{
s->append((char*)contents, newLength);
}
catch (std::bad_alloc &e)
{
return 0;
}
return newLength;
}
std::string CurlGetResponse(std::string url) {
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
std::string response;
if (curl)
{
curl_easy_setopt(curl, CURLOPT_USERNAME, "apikey");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "API Key");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //only for https
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); //only for https
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
return response;
}
int main()
{
std::string response = CurlGetResponse("url");
std::cout << response.data();
std::cout << response;
std::fstream file;
file.open("C:\Users\maste\HelloWorld_1.mp3", std::ios::binary);
file.write(response, sizeof(response));
file.close();
return 0;
}
声明
file.write(response, sizeof(response));
包含两个错误:
首先,它将
std::string
对象作为参数传递,但write
需要一个指向要写入的字节的指针。你需要通过例如response.data()
.第二个问题(我在评论中也提到了)是
sizeof(response)
是std::string
对象本身的大小,而不是它包含的字符串。您需要使用response.size()
来获取实际字符串的大小。
总而言之,声明应如下所示:
file.write(response.data(), response.size());