原:http://blog.csdn.net/mp295345033/article/details/49487347
最近做的一个任务,项目的需求,需要下载ftp上的全部文件,没有上传,只有下载,利用libcurl库,现在只做了linux版本。
头文件:
- #ifndef FTP_DOWNLOAD_H
- #define FTP_DOWNLOAD_H
- #include <iostream>
- #include <functional>
- using namespace std;
- typedef std::function<void(string &localpath,string &filename)> FileDownloadedCallBack;
- class FtpDownloadder
- {
- public:
- FtpDownloadder(const char *ip,const char *port,const char *username,const char *password);
- ~FtpDownloadder();
- bool Download(FileDownloadedCallBack callBack);
- private:
- string m_ip;
- string m_port;
- string m_username;
- string m_password;
- FileDownloadedCallBack m_callBack;
- bool Getlist(string &remotpath,string &myfloderlist,string &localpath);//获得每一个ftp目录的文件列表
- bool Downloadfile(string &remotpath,string &filename,string &localpath);//下载文件
- void Getfirstchar(string &filename,char &fistchar);//对文件名的操作
- };
- #endif
cpp文件:
- #include "download.h"
- #include <stdio.h>
- #include <iostream>
- #include <curl/curl.h>
- #include <fstream>
- #include <string.h>
- #include <vector>
- #include <sys/stat.h>
- #include <sys/types.h>
- using namespace std;
- struct FtpFile
- {
- string local;
- FILE *stream;
- };
- FtpDownloadder::FtpDownloadder(const char *ip,const char *port,const char *username,const char *password)
- {
- m_ip = ip;
- m_port = port;
- m_username = username;
- m_password = password;
- };
- FtpDownloadder::~FtpDownloadder(){};
- bool FtpDownloadder::Getlist(string &remotpath,string &myfloderlist,string &localpath)
- {
- CURL *curl;
- CURLcode res;
- char fistchar;
- FILE *ftpfile;
- string filename;
- int i=0;
- char listbuf[200];
- /* local file name to store the file as */
- ftpfile = fopen((myfloderlist+".txt").c_str(), "wb"); /* b is binary, needed on win32 */
- curl = curl_easy_init();
- if(curl) {
- /* Get a file listing from sunet */
- curl_easy_setopt(curl, CURLOPT_URL, remotpath.c_str());
- curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
- curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, ftpfile);
- res = curl_easy_perform(curl);
- /* Check for errors */
- if(res != CURLE_OK)
- fprintf(stderr, "curl_easy_perform() failed: %s\n",
- curl_easy_strerror(res));
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
- fclose(ftpfile);
- string strFtpListFile = myfloderlist+".txt";
- ifstream infile(strFtpListFile.c_str());
- if(!infile.is_open())
- {
- cout << "can not open ftpList.txt" << endl;
- return false;
- //return -1;
- }
- while(getline(infile,filename))
- {
- Getfirstchar(filename,fistchar);
- string nextdir = remotpath + filename + "/";
- string localpath1 = localpath + "/" + filename;
- strcpy(listbuf,strFtpListFile.c_str());
- sprintf(listbuf,"%d",i);
- string myfloderlist(listbuf);
- string folderlist=myfloderlist+".txt";
- i++;
- if('d'==fistchar)
- {
- int err=mkdir(localpath1.c_str(),S_IRWXU);
- if(-1==err)
- {
- cout<<"error mkdir "<<endl;
- }
- Getlist(nextdir,myfloderlist,localpath1);
- }
- else
- {
- string remotpath2=remotpath;
- if(Downloadfile(remotpath2,filename,localpath))
- {
- if (m_callBack!=NULL)
- m_callBack(localpath,filename);
- }
- else
- {
- cout << "download error";
- return false;
- }
- //vector<string> vec;
- //vec.pushback(localpath);
- }
- }
- /* close the local file */
- return true;
- }
- int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
- {
- struct FtpFile *out=(struct FtpFile *)stream;
- if(out && !out->stream)
- {
- /* open file for writing */
- out->stream=fopen((out->local).c_str(), "ab+");
- if(!out->stream)
- return -1; /* failure, can't open file to write */
- }
- return fwrite(buffer, size, nmemb, out->stream);
- }
- bool FtpDownloadder::Downloadfile(string &remotpath,string &filename,string &localpath)
- {
- CURL *curl;
- CURLcode res;
- curl_global_init(CURL_GLOBAL_DEFAULT);
- // long getlocal ;
- //FILE *destFilePath;
- int use_resume = 0;
- curl_off_t local_file_len = -1 ;
- struct stat file_info;
- if(stat(localpath.c_str(), &file_info) == 0)
- {
- local_file_len = file_info.st_size;
- use_resume = 1;
- }
- struct FtpFile ftpfile=
- {
- localpath+"/"+filename, /* name to store the file as if successful */
- NULL
- };
- curl = curl_easy_init();
- if(curl)
- {
- curl_easy_setopt(curl, CURLOPT_URL, (remotpath+filename).c_str());
- curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
- curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
- //curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1);
- curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, use_resume?local_file_len:0);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
- res = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
- }
- curl_global_cleanup();
- return true;
- }
- void FtpDownloadder::Getfirstchar(string &filename,char &fistchar)
- {
- vector<string>v1(sizeof(filename), filename);
- vector<string>::iterator it = v1.begin();
- int err = it->find_last_of(' ');
- string filename1;
- filename1.assign(it->begin()+err+1, it->end());
- const char *p = filename.c_str();
- filename=filename1;
- fistchar = *p;
- }
- bool FtpDownloadder::Download(FileDownloadedCallBack callBack)
- {
- m_callBack=callBack;
- string remotpath="ftp://"+m_ip+":"+m_port+"/";
- string list="mylist";
- string localpath="/home/FtpServer/";
- int err=mkdir("/home/FtpServer",S_IRWXU);
- if(-1==err)
- {
- return false;
- }
- if(Getlist(remotpath,list,localpath))
- {
- return false;
- }
- return true;
- }
- #include "download.h"
- #include <iostream>
- using namespace std;
- int main()
- {
- FileDownloadedCallBack callBack;
- FtpDownloadder *dl=new FtpDownloadder("192.168.1.1","21","zheng","yun");
- if(dl->Download(callBack))
- {
- cout<<"download over";
- }
- delete dl;
- return 0;
- }