您的位置:首页 > 编程语言

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

2008-12-12 18:21 766 查看
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://axiii.blog.51cto.com/396236/112836


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


下面是主程序的代码.


/***************************************************************


* 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)


{





}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: