程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 利用curl下載文件(進度條顯示) 代碼片段

利用curl下載文件(進度條顯示) 代碼片段

編輯:關於C++

在項目中需要用到程序更新的功能,同事介紹說是curl中的開發庫很牛x,又是跨平台(他們 總是這麼喜歡跨平台的東西 *_*),於是下載這個包測試了一下,確實不錯。准備正式用到項 目中,以下一個例子用於從互聯網上抓取一個文件下載到本地,並加上進度條顯示,做得挺 簡陋,不過功能差不多就這樣了。

程序運行預覽.

首先需要 加入多線程的機制,因為程序一邊在下載文件,一邊在顯示進度條,單線程的方式肯定不行 ,所以我用到了wxTimer來實現,在downloadMain.h 中定義了一個wxTimer,並做了事件申 明.

DECLARE_EVENT_TABLE()

/***************************************************************
* Name:       downloadMain.h
* Purpose:   Defines Application Frame
* Author:     (alan)
* Created:   2008-11-14
* Copyright:  (謙泰 通訊)
* License:
**************************************************************/
#ifndef DOWNLOADMAIN_H
#define DOWNLOADMAIN_H

#include "downloadApp.h"
#include <wx/timer.h>
#include "GUIDialog.h"
class downloadDialog: public GUIDialog
{
    public:
        downloadDialog(wxDialog *dlg);
         ~downloadDialog();
        void OnTimer(wxTimerEvent& event);
    private:
        virtual void OnClose (wxCloseEvent& event);
        virtual void OnQuit (wxCommandEvent& event);
        virtual void OnAbout (wxCommandEvent& event);
        void downloadfile();
         wxTimer* m_timerdown;
        DECLARE_EVENT_TABLE()
};
#endif // DOWNLOADMAIN_H

下面是主程序的代 碼.

/***************************************************************< br />* Name:      downloadMain.cpp
* Purpose:   Code for Application Frame
* Author:     (alan)
* Created:   2008-11-14
* Copyright:  (謙泰通訊)
* License:
**************************************************************/
#ifdef WX_PRECOMP
#include "wx_pch.h"
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif //__BORLANDC__
#include "downloadMain.h"
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include "update.h"
#include <wx/msgdlg.h>
#include <wx/utils.h>
#define TIMER_ID 22222
//事件監聽聲明
BEGIN_EVENT_TABLE(downloadDialog, GUIDialog)
    EVT_TIMER(TIMER_ID, downloadDialog::OnTimer)
END_EVENT_TABLE()
enum wxbuildinfoformat
{
    short_f, long_f
};
wxString wxbuildinfo (wxbuildinfoformat format)
{
    wxString wxbuild (wxVERSION_STRING);
    if (format == long_f )
    {
#if defined(__WXMSW__)
        wxbuild << _T("- Windows");
#elif defined(__WXMAC__)
        wxbuild << _T("-Mac");
#elif defined(__UNIX__)
         wxbuild << _T("-Linux");
#endif
#if wxUSE_UNICODE
        wxbuild << _T("-Unicode build");
#else
        wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
    }
    return wxbuild;
}
//聲明一個 文件結構體
struct FtpFile
{
    char *filename;
     FILE *stream;
};
downloadDialog::downloadDialog(wxDialog *dlg)
         : GUIDialog(dlg)
{
    //創建一個定時器,制定 TIMER_ID
    m_timerdown = new wxTimer(this, TIMER_ID);
    // 定時器開始運行,這裡會自動執行OnTimer函數
    m_timerdown->Start (100);
}
downloadDialog::~downloadDialog()
{
}
//定時器 操作
void downloadDialog::OnTimer(wxTimerEvent &event)
{
     downloadfile();
}
//文件寫入流
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
    struct FtpFile *out=(struct FtpFile *)stream;
    if (out && !out->stream)
    {
        out->stream=fopen(out->filename, "wb");
        if (!out->stream)
         {
            return -1;
        }
    }
    return fwrite(buffer, size, nmemb, out->stream);
}
// 進度條顯示函數
int wxcurldav_dl_progress_func(void* ptr, double rDlTotal, double rDlNow, double rUlTotal, double rUlNow)
{
  wxGauge* pGauge = (wxGauge*) ptr;
  if(pGauge)
  //設置進度條的值
   pGauge->SetValue(100.0 * (rDlNow/rDlTotal));
  return 0;
}
//下載文件函數
void downloadDialog::downloadfile()
{
     //創建curl對象
    CURL *curl;
    CURLcode res;
     m_staticText2->SetLabel(wxT("請耐心等待程序下載更新包..."));
    struct FtpFile ftpfile=
    {
      //定義下載到本地的文件位置和路徑
       "tmp.exe",NULL
     };
    curl_global_init(CURL_GLOBAL_DEFAULT);
    //curl初始 化
    curl = curl_easy_init();
    //curl對象存在的情況下執行 操作
    if (curl)
    {
        //設置遠端地址
        curl_easy_setopt(curl, CURLOPT_URL,"http://dl_dir.qq.com/minigamefile/QQGame2008ReleaseP2_web_setup .EXE");
         //執行寫入文件流操作
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
        //curl的進度條聲明
         curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
         //回調進度條函數
        curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, wxcurldav_dl_progress_func);
        //設 置進度條名稱
        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, m_gauge1);
        //進度條
        m_gauge1- >SetValue(0);
        //寫入文件
        res = curl_easy_perform(curl);
        m_gauge1->SetValue(100);
         //釋放curl對象
        curl_easy_cleanup(curl);
        if (CURLE_OK != res)
            ;
     }
    if (ftpfile.stream)
    {
        //關閉文件 流
        fclose(ftpfile.stream);
    }
         //釋放全局curl對象
        curl_global_cleanup();
         //這一步很重要,停止定時器,不然程序會無休止的運行下去
         m_timerdown->Stop();
        //執行剛下載完畢的程序,進行程序更 新
        int pid = ::wxExecute(_T("tmp.exe"));
         wxMessageBox(wxT("下載完畢,程序開始執行更新操 作......"));
}
void downloadDialog::OnClose(wxCloseEvent &event)
{
    Destroy();
}
void downloadDialog::OnQuit(wxCommandEvent &event)
{
    Destroy ();
}
void downloadDialog::OnAbout(wxCommandEvent &event)
{
}

本文出自 “阿汐的博客” 博客,請務必保留此出處 http://axiii.blog.51cto.com/396236/112836

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved