C++利用libcurl獲取下載文件名稱及大小
顯示效果
客戶端利用libcurl庫下載文件,一般需要預先知道文件名稱及大小以及下載進度、下載速度等,以便用戶通過界面顯示實時下載狀態(tài)及信息。

1、從下載url鏈接獲取文件名字
如何通過一個文件的下載鏈接(url)獲取到需要下載的文件名稱是我們經(jīng)常要遇到的一個問題。通常是通過獲取header中的Content-Disposition字段來進行解析獲取。
Content-disposition 是 MIME 協(xié)議的擴展,MIME 協(xié)議指示 MIME 用戶代理如何顯示附加的文件。Content-disposition其實可以控制用戶請求所得的內(nèi)容存為一個文件的時候提供一個默認的文件名,文件直接在瀏覽器上顯示或者在訪問時彈出文件下載對話框。
該字段包含了兩種返回值:
1、inline:將文件內(nèi)容直接顯示在頁面
Content-Disposition: inline;filename=hello.jpg
2、attachment:彈出對話框讓用戶下載
Content-Disposition: attachment;filename=hello.jpg
可以看出無論是哪種返回值,其中都包括了filename,“=”后面就是我們需要的文件名稱。但是有時會出現(xiàn)獲取到的文件名稱存在中文亂碼問題(可能包含非 ASCII 字符)。
2、LibCurl官方示例
Example
static size_t header_callback(char *buffer, size_t size,
size_t nitems, void *userdata)
{
/* received header is nitems * size long in 'buffer' NOT ZERO TERMINATED */
/* 'userdata' is set with CURLOPT_HEADERDATA */
return nitems * size;
}
CURL *curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
curl_easy_perform(curl);
}
3、實例
// Get the file size and name on the server
size_t header_callback(void *buffer, size_t size, size_t nitems, void *userdata)
{
string sHeaderData = (char*)buffer;
string sKey = "Content-Disposition";
std::size_t nFound = sHeaderData.find(sKey);
if (nFound != std::string::npos)
{
printf("Header data: %s \n", (char*)buffer);
stringstream ss(sHeaderData);
char cSplit = ';'; // 設定好分隔符號
sKey = "filename=";
vector<string> results; // 用來存儲結(jié)果
string strResult;
while (getline(ss, strResult, cSplit))
{
nFound = strResult.find(sKey);
if (nFound != std::string::npos)
{
string sFileName = strResult.substr(nFound + sKey.length());
sKey = '"';
nFound = sFileName.find(sKey);
if (nFound != std::string::npos)
{
sFileName = sFileName.substr(1, sFileName.length()-2);
}
m_sFileName = sFileName;
printf("sFileName: %s \n", m_sFileName.c_str());
break;
}
}
}
return nitems * size;
}
double getDownloadFileInfo(const string url)
{
CURL *easy_handle = NULL;
int ret = CURLE_OK;
double size = -1;
do
{
easy_handle = curl_easy_init();
if (!easy_handle)
{
ZLOG("curl_easy_init error");
break;
}
// Only get the header data
curl_easy_setopt(easy_handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, "GET"); //使用CURLOPT_CUSTOMREQUEST
//ret |= curl_easy_setopt(easy_handle, CURLOPT_HEADER, 1L);
curl_easy_setopt(easy_handle, CURLOPT_NOBODY, 1L);
//ret |= curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, nousecb);
curl_easy_setopt(easy_handle, CURLOPT_HEADERFUNCTION, header_callback);
ret = curl_easy_perform(easy_handle);
if (ret != CURLE_OK)
{
char s[100] = {0};
sprintf_s(s, sizeof(s), "error:%d:%s", ret, curl_easy_strerror(static_cast<CURLcode>(ret)));
ZLOG(s);
break;
}
// size = -1 if no Content-Length return or Content-Length=0
ret = curl_easy_getinfo(easy_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &size);
if (ret != CURLE_OK)
{
ZLOG("curl_easy_getinfo error");
break;
}
} while (0);
curl_easy_cleanup(easy_handle);
if (size > 0.0)
{
downloadFileLength = size;
}
return size;
}
到此這篇關于C++利用libcurl獲取下載文件名稱及大小的文章就介紹到這了,更多相關C++ libcurl獲取文件名稱大小內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Eclipse對printf()不能輸出到控制臺的快速解決方法
Eclipse對printf()不能輸出到控制臺的快速解決方法。需要的朋友可以過來參考下,希望對大家有所幫助2013-10-10
C語言設計圖書登記系統(tǒng)與停車場管理系統(tǒng)的實例分享
這篇文章主要介紹了C語言設計圖書登記系統(tǒng)與停車場管理系統(tǒng)的實例分享,重在以最簡單的一些需求來展示管理系統(tǒng)的設計思路,需要的朋友可以參考下2016-06-06
C++中調(diào)用復制(拷貝)函數(shù)的三種情況總結(jié)
這篇文章主要介紹了C++中調(diào)用復制(拷貝)函數(shù)的三種情況總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11

