当前位置:首页 >> 编程开发 >> Visual C++ >> 内容

利用curl下载文件(进度条显示) 代码片段

时间:2015/5/19 21:33:44 作者:平凡之路 来源:xuhantao.com 浏览:

在项目中需要用到程序更新的功能,同事介绍说是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

相关文章
  • 没有相关文章
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
  • 徐汉涛(www.xuhantao.com) © 2024 版权所有 All Rights Reserved.
  • 部分内容来自网络,如有侵权请联系站长尽快处理 站长QQ:965898558(广告及站内业务受理) 网站备案号:蒙ICP备15000590号-1