1. 程式人生 > >使用libcurl下載文件小例

使用libcurl下載文件小例

true 自己的 seh har erase == win name code

libcurl是一個很強大的開源網絡處理庫,支持包括HTTP、HTTPS、FTP……一系列網絡協議。用它來進行HTTP的get\post 或者下載文件更是小菜一碟,chrome內核都用到了它,本文主要講解一個使用curl下載文件的小例。

首先是去下載curl的最新源代碼,然後編譯成動態庫或者靜態庫;然後把頭文件和庫文件拿出來加入到我們自己的工程中,引用聲明:

#include "curl.h"  
#ifdef _DEBUG  
#pragma comment(lib, "../Debug/libcurld")  
#else  
#pragma comment(lib, "../Release/libcurl")  
#endif

特意在原有代碼上加了一些註釋,希望可以更好理解,上代碼:

<pre name="code" class="cpp">// UseLibCurl.cpp : 定義控制臺應用程序的入口點。  
//  
  
#include "stdafx.h"  
#include <Windows.h>  
#include <CommCtrl.h>  
#include "resource.h"  
#include "curl.h"  
#ifdef _DEBUG  
#pragma comment(lib, "../Debug/libcurld")  
#else  
#pragma
comment(lib, "../Release/libcurl") #endif //這個用來保存對話框的窗口句柄,因為後面要向這個窗口發消息,必須知道其窗口句柄 HWND g_hDlgWnd = NULL; //提供給CURL下載進度回調的函數,用於保存下載的數據到文件 static size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam); //提供給CURL下載進度回調的函數,用於計算下載進度通知界面 static int ProgressCallback(void
*clientp, double dltotal, double dlnow, double ultotal, double ulnow); //這是對話框的消息循環,在控制臺程序裏面創建GUI,僅僅是為了更好地展現下載回調這個功能 INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); //這個是下載的線程函數,為了不把對話框主界面卡死,肯定是要自己開線程來下載的了 DWORD WINAPI DownloadThread(LPVOID lpParam); int _tmain(int argc, _TCHAR* argv[]) { //彈出對話框,知道對話框關閉才會執行退出 DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc ); return 0; } static size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam) { //把下載到的數據以追加的方式寫入文件(一定要有a,否則前面寫入的內容就會被覆蓋了) FILE* fp = NULL; fopen_s(&fp, "c:\\test.apk", "ab+"); size_t nWrite = fwrite(pBuffer, nSize, nMemByte, fp); fclose(fp); return nWrite; } static int ProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { if ( dltotal > -0.1 && dltotal < 0.1 ) return 0; int nPos = (int) ( (dlnow/dltotal)*100 ); //通知進度條更新下載進度 ::PostMessage(g_hDlgWnd, WM_USER + 110, nPos, 0); //::Sleep(10); return 0; } INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch( uMsg ) { case WM_INITDIALOG: { g_hDlgWnd = hWnd; HWND hProgress = GetDlgItem(hWnd, IDC_PROGRESS1); SendMessage(hProgress, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) 100); //對話框初始化時創建下載線程 HANDLE hThread = CreateThread(NULL, 0, DownloadThread, 0, 0, NULL); CloseHandle(hThread); ::SetWindowText(hWnd, L"使用CURL下載文件示例:"); return TRUE; } case WM_COMMAND: { WORD msg = HIWORD(wParam); WORD id = LOWORD(wParam); if ( id == IDOK || id == IDCANCEL ) EndDialog(hWnd, id); break; } case WM_ERASEBKGND: return TRUE; case WM_CTLCOLORSTATIC: return (INT_PTR)(HBRUSH)::GetStockObject(WHITE_BRUSH); case WM_USER + 110: {//接收到設置進度的消息 HWND hProgress = GetDlgItem(hWnd, IDC_PROGRESS1); HWND hStatus = GetDlgItem(hWnd, IDC_STATUS); if ( hProgress ) SendMessage(hProgress, PBM_SETPOS, wParam, 0L); if ( hStatus ) { WCHAR szBuffer[100] = {0}; if ( wParam<100 ) swprintf(szBuffer, L"正在下載文件,進度:%d%%", wParam); else swprintf(szBuffer, L"文件下載完畢!"); ::SetWindowText(hStatus, szBuffer); } return 0; } default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } DWORD WINAPI DownloadThread(LPVOID lpParam) { //初始化curl,這個是必須的 CURL* curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, "http://android.shoujids.com/software/download?id=154103"); //設置接收數據的回調 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DownloadCallback); //curl_easy_setopt(curl, CURLOPT_INFILESIZE, lFileSize); //curl_easy_setopt(curl, CURLOPT_HEADER, 1); //curl_easy_setopt(curl, CURLOPT_NOBODY, 1); //curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // 設置重定向的最大次數 curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5); // 設置301、302跳轉跟隨location curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); //設置進度回調函數 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, ProgressCallback); //curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &lFileSize); //curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, g_hDlgWnd); //開始執行請求 CURLcode retcCode = curl_easy_perform(curl); //查看是否有出錯信息 const char* pError = curl_easy_strerror(retcCode); //清理curl,和前面的初始化匹配 curl_easy_cleanup(curl); return 0; }

技術分享

原文鏈接:使用libcurl下載文件小例

使用libcurl下載文件小例