[原创]封装了个基于Libcurl的类,
大家评评,尽情拍砖.
1 #pragma once
2 #include <iostream>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include "curl/curl.h"
6 #include "curl/types.h"
7 #include "curl/easy.h"
8 #pragma comment(lib, "curl/libcurl.lib");
9 struct CURL_FtpFile {
10 const char *filename;
11 FILE *stream;
12 };
13
14 template<typename T>
15 class CFtpClient{
16 public:
17 bool m_bDebug;
18 char m_szFtpHost[1024];
19 char m_szFtpUSERPWD[256];
20 CFtpClient();
21 bool close();
22 bool open(char szFtpHost[],char szFtpUserName[],char szFtpPassword[],int nPort=21);
23 bool GetFile(char szRemoteFileName[],char szLocalFileName[] ,T* pT=NULL);
24 bool PutFile(char szLocalFileName[] ,char szRemoteFileName[],T* pT=NULL);
25 bool RemoveFile(char szRemoteFileName[]);
26 bool RemoveDir(char szRemoteDirectory[]);
27
28 size_t GetLocalFileSize(char* szFileName);
29
30 private:
31 static size_t ReadLocalFileFunc (void *ptr, size_t size, size_t nmemb, void *stream);
32 static size_t WriteLocalFileFunc(void *buffer, size_t size, size_t nmemb, void *stream);
33 static int PutFileProgressFunc(void *clientp,
34 double dltotal,
35 double dlnow,
36 double ultotal, //上传:总大小
37 double ulnow //上传:当前大小
38 );
39
40 static int GetFileProgressFunc(void *clientp,
41 double dltotal, //下载:当前大小
42 double dlnow, //下载:当前大小
43 double ultotal,
44 double ulnow);
45 };
46
47
48 template<typename T>
49 CFtpClient<T>::CFtpClient(void):m_bDebug(false)
50 {
51 }
52
53 template<typename T>
54 bool CFtpClient<T>::open(char szFtpHost[],char szFtpUserName[],char szFtpPassword[],int nPort) {
55 sprintf(m_szFtpHost,"ftp://%s:%d/",szFtpHost,nPort);
56 sprintf(m_szFtpUSERPWD,"%s:%s",szFtpUserName,szFtpPassword);
57 curl_global_init(CURL_GLOBAL_DEFAULT);
58 return true;
59 }
60
61 template<typename T>
62 bool CFtpClient<T>::close() {
63 curl_global_cleanup();
64 return true;
65 }
66
67 //FTP回调函数:读
68 template<typename T>
69 size_t CFtpClient<T>::ReadLocalFileFunc(void *ptr, size_t size, size_t nmemb, void *stream) {
70 return fread(ptr, size, nmemb, (FILE *)stream) * size;
71 }
72
73 //FTP回调函数:写
74 template<typename T>
75 size_t CFtpClient<T>::WriteLocalFileFunc(void *buffer, size_t size, size_t nmemb, void *stream) {
76 struct CURL_FtpFile *out=(struct CURL_FtpFile *)stream;
77 if(out && !out->stream) {
78 out->stream=fopen(out->filename, "wb");
79 if(!out->stream)
80 return -1; /* failure, can't open file to write */
81 }
82 return fwrite(buffer, size, nmemb, out->stream);
83 }
84
85 template<typename T>
86 int CFtpClient<T>::PutFileProgressFunc(void *clientp,
87 double dltotal,
88 double dlnow,
89 double ultotal, //上传:总大小
90 double ulnow //上传:当前大小
91 )
92 {
93 T *pT = (T*)clientp;
94 return pT->uploading(ulnow,ultotal);
95 }
96
97 template<typename T>
98 int CFtpClient<T>::GetFileProgressFunc(void *clientp,
99 double dltotal, //下载:总大小
100 double dlnow, //下载:当前大小
101 double ultotal,
102 double ulnow)
103
104 {
105 T *pT = (T*)clientp;
106 return pT->downloading(dlnow,dltotal);
107 }
108
109
110 //获取本地文件的大小
111 template<typename T>
112 size_t CFtpClient<T>::GetLocalFileSize(char* szFileName) {
113 struct stat f_stat;
114 if (stat(szFileName, &f_stat) == -1) {
115 return -1;
116 }
117 return (size_t)f_stat.st_size;
118 }
119
120 template<typename T>
121 bool CFtpClient<T>::GetFile(char szRemoteFileName[],char szLocalFileName[] ,T* pT) {
122 CURL* curl;
123 CURLcode res = CURL_LAST;
124
125 curl = curl_easy_init();
126 if (curl == NULL) {
127 return false;
128 }
129 curl_easy_setopt(curl, CURLOPT_USERPWD, m_szFtpUSERPWD);
130
131 //得到全路径文件名
132 char szRemoteFullPathFileName[1024];
133 strcat(szRemoteFullPathFileName,m_szFtpHost);
134 strcat(szRemoteFullPathFileName,szRemoteFileName);
135
136 struct CURL_FtpFile ftpLocalFile={
137 szLocalFileName,
138 NULL
139 };
140
141 //设置远程URL
142 curl_easy_setopt(curl, CURLOPT_URL,szRemoteFullPathFileName);
143
144 //设置回调函数
145 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CFtpClient::WriteLocalFileFunc);
146 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpLocalFile);
147 if (pT !=NULL){
148 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
149 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, CFtpClient::GetFileProgressFunc);
150 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,pT);
151 }
152
153 res = curl_easy_perform(curl);
154 curl_easy_cleanup(curl);
155 if (ftpLocalFile.stream){
156 fclose(ftpLocalFile.stream);
157 }
158 if (res != CURLE_OK){
159 return false;
160 }
161 return true;
162 }
163
164 template<typename T>
165 bool CFtpClient<T>::PutFile(char szLocalFileName[] ,char szRemoteFileName[],T* pT)
166 {
167 if (strlen(szLocalFileName)<1 || strlen(szRemoteFileName) <1) {
168 return false;
169 }
170 CURL* curl;
171 CURLcode res = CURL_LAST;
172
173 curl = curl_easy_init();
174 if (curl == NULL) {
175 return false;
176 }
177 FILE* pLocalFile;
178 pLocalFile = fopen(szLocalFileName,"rb");
179 if (pLocalFile==NULL) {
180 return false;
181 }
182 char szRemoteFullPathFileName[2048];
183 memset(szRemoteFullPathFileName,'\0',2048);
184 strcat(szRemoteFullPathFileName,m_szFtpHost);
185 strcat(szRemoteFullPathFileName,szRemoteFileName);
186
187 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
188 curl_easy_setopt(curl, CURLOPT_URL, szRemoteFullPathFileName);
189 curl_easy_setopt(curl, CURLOPT_USERPWD,m_szFtpUSERPWD);
190 curl_easy_setopt(curl, CURLOPT_READDATA, pLocalFile);
191 curl_easy_setopt(curl, CURLOPT_READFUNCTION,CFtpClient::ReadLocalFileFunc);
192 //curl_easy_setopt(curl, CURLOPT_INFILESIZE ,GetLocalFileSize(szLocalFullPathFileName));
193 curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,(curl_off_t)GetLocalFileSize(szLocalFileName));
194 curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1);
195 if (this->m_bDebug){
196 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
197 }
198
199 //设置进度处理
200 if (pT !=NULL){
201 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
202 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, CFtpClient::PutFileProgressFunc);
203 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,pT);
204 }
205 res = curl_easy_perform(curl);
206 curl_easy_cleanup(curl);
207 if (pLocalFile) {
208 fclose(pLocalFile);
209 }
210 //用户取消
211 if (res == CURLE_ABORTED_BY_CALLBACK){
212 this->RemoveFile(szRemoteFileName);
213 return false;
214 }
215
216 if (res != CURLE_OK) {
217 return false;
218 }
219 return true;
220 }
221
222 // 删除文件
223 template<typename T>
224 bool CFtpClient<T>::RemoveFile(char szRemoteFileName[])
225 {
226 CURL* curl;
227 CURLcode res = CURL_LAST;
228 curl = curl_easy_init();
229 if (curl == NULL) {
230 return false;
231 }
232 struct curl_slist *headerlist=NULL;
233 char szCmd[1024] = "DELE ";
234
235 strcat(szCmd,szRemoteFileName);
236
237 headerlist = curl_slist_append(headerlist, szCmd);
238 curl_easy_setopt(curl, CURLOPT_URL,m_szFtpHost);
239 curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
240 curl_easy_setopt(curl, CURLOPT_USERPWD, m_szFtpUSERPWD);
241 res = curl_easy_perform(curl);
242 curl_easy_cleanup(curl);
243 return (res == CURLE_OK);
244 }
245
246 // 删除目录
247 template<typename T>
248 bool CFtpClient<T>::RemoveDir(char szRemoteDirectory[])
249 {
250 CURL* curl;
251 CURLcode res = CURL_LAST;
252 curl = curl_easy_init();
253 if (curl == NULL) {
254 return false;
255 }
256 struct curl_slist *headerlist=NULL;
257 char szCmd[1024] = "RMD ";
258 strcat(szCmd,szRemoteDirectory);
259 headerlist = curl_slist_append(headerlist, szCmd);
260 curl_easy_setopt(curl, CURLOPT_URL,m_szFtpHost);
261 curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
262 curl_easy_setopt(curl, CURLOPT_USERPWD, m_szFtpUSERPWD);
263 if (this->m_bDebug){
264 curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1);
265 }
266 res = curl_easy_perform(curl);
267 curl_easy_cleanup(curl);
268 return (res == CURLE_OK);
269 }
270