FTP客户端上传下载实现

1、第一次感觉MS也有这么难用的MFC类;

2、CFtpFileFind类只能实例化一个,多个实例同时查找会出错(因此下载时不能递归);

3、本程序支持文件夹嵌套上传下载;

4、boost::filesystem::create_directory不能递归创建文件夹,需手动实现

代码如下:

CFtpClient.h

 1 #ifndef __ftp_client_h__
 2 #define __ftp_client_h__
 3
 4 #include <afxinet.h>
 5 #include <iostream>
 6 #include <sstream>
 7 #include <queue>
 8 #include <boost/filesystem/operations.hpp>
 9 #include <boost/filesystem/path.hpp>
10
11 class CFtpClient
12 {
13 public:
14     CFtpClient();
15     ~CFtpClient();
16
17     bool Connect();
18     bool Close();
19     int Download(std::string strServerDir = "\\", std::string strFilename = "*");
20     int Upload(const std::string strLocalPath);
21 private:
22     //下载文件夹
23     int DownloadFolder();
24     //下载文件
25     int DownloadFile(std::string strServerDir, std::string strFilename);
26     //创建多级目录
27     void CreateDirectory(boost::filesystem::path path);
28 private:
29     CInternetSession* m_pInternetSession;
30     CFtpConnection* m_pFtpConnection;
31
32     //参数配置
33     std::string m_strServerAddress;               //FTP:服务器地址
34     int m_nServerPort;                            //FTP:服务器端口号
35     std::string m_strUsername;                    //FTP:登录用户名
36     std::string m_strPassword;                    //FTP:登录密码
37     //上传目录
38     std::string m_strUploadServerDir;             //上传服务器存储目录
39     //下载目录
40     std::string m_strDownloadLocalDir;            //下载本地存储目录
41
42     std::queue<std::string> queServerDir;
43 };
44
45
46 #endif

CFtpClient.cpp

  1 // 模块名称:
  2 // 模块描述:FTP上传下载类
  3 // 开发作者:可笑痴狂
  4 // 创建日期:2015-12-04
  5 // 模块版本:1.0.0.0
  6 //------------------------------------------------------------------------------
  7
  8 #include <string>
  9 #include <iostream>
 10 #include <sstream>
 11 #include "CFtpClient.h"
 12 #include <boost/assert.hpp>
 13 #include <boost/lexical_cast.hpp>
 14 #include <boost/foreach.hpp>
 15
 16
 17 CFtpClient::CFtpClient()
 18 {
 19     m_pInternetSession = NULL;
 20     m_pFtpConnection = NULL;
 21     m_strServerAddress = "127.0.0.1";
 22     m_strUsername = "123";
 23     m_strPassword = "123";
 24     m_nServerPort = 21;
 25     m_strDownloadLocalDir = "D:\\DownloadLocal";
 26     m_strUploadServerDir = "\\";
 27 }
 28
 29 CFtpClient::~CFtpClient()
 30 {
 31     this->Close();
 32 }
 33
 34 bool CFtpClient::Connect()
 35 {
 36     if (m_pInternetSession != NULL)
 37     {
 38         return true;
 39     }
 40
 41     m_pInternetSession = new CInternetSession("OTC_FTP_Client");
 42     int nCnt = 1;
 43     while(nCnt++)
 44     {
 45         try
 46         {
 47             m_pFtpConnection = m_pInternetSession->GetFtpConnection(m_strServerAddress.c_str(), m_strUsername.c_str(), m_strPassword.c_str(),                                           m_nServerPort);
 48         }
 49         catch(CInternetException *pEx)
 50         {
 51             char szErrMsg[1024+1] = {0};
 52             if (pEx->GetErrorMessage(szErrMsg, 1024))
 53             {
 54                 std::cout << "连接FTP服务器失败, ErrMsg:" << szErrMsg << std::endl;
 55                 if (nCnt > 5)
 56                 {
 57                     return false;
 58                 }
 59                 std::cout << "正在尝试重新连接[" << nCnt-1 << "]......" << std::endl;
 60             }
 61             continue;
 62         }
 63         return true;
 64     }
 65
 66     return true;
 67 }
 68
 69 bool CFtpClient::Close()
 70 {
 71     if (NULL != m_pInternetSession)
 72     {
 73         m_pInternetSession->Close();
 74         delete m_pInternetSession;
 75         m_pInternetSession = NULL;
 76     }
 77     if (NULL != m_pFtpConnection)
 78     {
 79         m_pFtpConnection->Close();
 80         delete m_pFtpConnection;
 81         m_pFtpConnection = NULL;
 82     }
 83
 84     return true;
 85 }
 86 int CFtpClient::Download(std::string strServerDir /*="\\"*/, std::string strFilename /*= "*"*/)
 87 {
 88     if ("*" == strFilename)
 89     {
 90         queServerDir.push(strServerDir);
 91         return this->DownloadFolder();
 92     }
 93     else
 94     {
 95         return this->DownloadFile(strServerDir, strFilename);
 96     }
 97
 98 }
 99 int CFtpClient::DownloadFile(std::string strServerDir, std::string strFilename)
100 {
101     int nRet = 0;
102     CFtpFileFind* pFtpFileFind = NULL;
103     if(!this->Connect())
104     {
105         nRet = -1;
106         goto __end;
107     }
108     else
109     {
110         boost::filesystem::path LocalPath(m_strDownloadLocalDir);
111         if (!boost::filesystem::exists(LocalPath))
112         {
113             this->CreateDirectory(LocalPath);
114         }
115         if (0 == m_pFtpConnection->SetCurrentDirectory(strServerDir.c_str()))
116         {
117             nRet = -1;
118             std::cout << "设置服务器下载目录[" << strServerDir << "]失败!ErrCode=" << GetLastError() << std::endl;
119             DWORD dw = 0;
120             char szBuf[512]={0};
121             DWORD dwLen = sizeof(szBuf)-1;
122             InternetGetLastResponseInfo(&dw, szBuf, &dwLen);
123             std::cout << "错误信息:" << szBuf << std::endl;
124             goto __end;
125         }
126         if (pFtpFileFind == NULL)
127         {
128             pFtpFileFind = new CFtpFileFind(m_pFtpConnection);
129         }
130         int nRet = pFtpFileFind->FindFile(strFilename.c_str());
131         if(nRet)
132         {
133             nRet = pFtpFileFind->FindNextFile();
134
135             std::string strLocalFilename = m_strDownloadLocalDir + "\\" + strFilename;
136             std::string strServerFilename = strFilename;
137             if(m_pFtpConnection->GetFile(strServerFilename.c_str(), strLocalFilename.c_str(), FALSE))
138                 std::cout << "下载文件[" << strServerFilename << "]到[" << strLocalFilename << "]成功!" << std::endl;
139             else
140             {
141                 std::cout << "下载文件[" << strServerFilename << "]到[" << strLocalFilename << "]失败!" << std::endl;
142                 char szBuf[512]={0};
143                 DWORD dw = 0;
144                 DWORD dwLen = sizeof(szBuf)-1;
145                 InternetGetLastResponseInfo(&dw, szBuf, &dwLen);
146                 dw = GetLastError();
147                 std::cout << "错误信息:" << szBuf << std::endl;
148                 nRet = -1;
149             }
150         }
151     }
152 __end:
153     this->Close();
154     if (pFtpFileFind)
155     {
156         pFtpFileFind->Close();
157         delete pFtpFileFind;
158     }
159
160     return nRet;
161 }
162 int CFtpClient::DownloadFolder()
163 {
164     std::string strServerDir;
165     std::string strFilename;
166     CFtpFileFind* pFtpFileFind = NULL;
167     int nRet = 0;
168
169     if(!this->Connect())
170     {
171         nRet = -1;
172         goto __end;
173     }
174     else
175     {
176         while(!queServerDir.empty())
177         {
178             strServerDir = queServerDir.front();
179             queServerDir.pop();
180
181             boost::filesystem::path LocalPath(m_strDownloadLocalDir);
182             if (!boost::filesystem::exists(LocalPath / strServerDir))
183             {
184                 this->CreateDirectory(LocalPath / strServerDir);
185             }
186
187             if (0 == m_pFtpConnection->SetCurrentDirectory(strServerDir.c_str()))
188             {
189                 nRet = -1;
190                 std::cout << "设置服务器下载目录[" << strServerDir << "]失败!ErrCode=" << GetLastError() << std::endl;
191                 DWORD dw = 0;
192                 char szBuf[512]={0};
193                 DWORD dwLen = sizeof(szBuf)-1;
194                 InternetGetLastResponseInfo(&dw, szBuf, &dwLen);
195                 std::cout << "错误信息:" << szBuf << std::endl;
196                 goto __end;
197             }
198             if (pFtpFileFind == NULL)
199             {
200                 pFtpFileFind = new CFtpFileFind(m_pFtpConnection);
201             }
202
203             int nRet = pFtpFileFind->FindFile();
204             while(nRet)
205             {
206                 nRet = pFtpFileFind->FindNextFile();
207                 strFilename = pFtpFileFind->GetFilePath();
208                 if (pFtpFileFind->IsDirectory())
209                 {
210                     queServerDir.push(std::string(pFtpFileFind->GetFilePath()));
211                     continue;
212                 }
213
214                 std::string strLocalFilename = m_strDownloadLocalDir + strFilename;
215                 std::string strServerFilename = strFilename;
216
217                 if(m_pFtpConnection->GetFile(strServerFilename.c_str(), strLocalFilename.c_str(), FALSE))
218                     std::cout << "下载文件[" << strServerFilename << "]到[" << strLocalFilename << "]成功!" << std::endl;
219                 else
220                 {
221                     std::cout << "下载文件[" << strServerFilename << "]到[" << strLocalFilename << "]失败!" << std::endl;
222                     char szBuf[512]={0};
223                     DWORD dw = 0;
224                     DWORD dwLen = sizeof(szBuf)-1;
225                     InternetGetLastResponseInfo(&dw, szBuf, &dwLen);
226                     dw = GetLastError();
227                     std::cout << "错误信息:" << szBuf << std::endl;
228                     nRet = -1;
229                 }
230             }
231         }
232     }
233 __end:
234     this->Close();
235     if (pFtpFileFind != NULL)
236     {
237         pFtpFileFind->Close();
238         delete pFtpFileFind;
239     }
240     return nRet;
241 }
242
243 int CFtpClient::Upload(const std::string strLocalPath)
244 {
245     int nRet = 0;
246     CFtpFileFind* pFtpFileFind = NULL;
247     const boost::filesystem::path& localPath(strLocalPath);
248
249     if(!this->Connect())
250     {
251         nRet = -1;
252         goto __end;
253     }
254     else
255     {
256         if (0 == m_pFtpConnection->SetCurrentDirectory(m_strUploadServerDir.c_str()))
257         {
258             nRet = -1;
259             std::cout << "设置服务器上传目录[" << m_strUploadServerDir << "]失败!ErrCode=" << GetLastError() << std::endl;
260             DWORD dw = 0;
261             char szBuf[512]={0};
262             DWORD dwLen = sizeof(szBuf)-1;
263             InternetGetLastResponseInfo(&dw, szBuf, &dwLen);
264             std::cout << "错误信息:" << szBuf << std::endl;
265             goto __end;
266         }
267
268         if (boost::filesystem::exists(localPath))
269         {
270             if (boost::filesystem::is_directory(localPath))
271             {
272                 m_pFtpConnection->CreateDirectory(localPath.leaf().string().c_str());
273
274                 boost::filesystem::directory_iterator itor_begin(localPath);
275                 boost::filesystem::directory_iterator itor_end;
276
277                 std::string strServerDir = m_strUploadServerDir;
278                 for (; itor_begin != itor_end; itor_begin++)
279                 {//回溯算法
280                     m_strUploadServerDir += std::string("\\") + localPath.leaf().string();
281                     this->Upload(itor_begin->path().string());
282                     m_strUploadServerDir = strServerDir;
283                 }
284             }
285             else
286             {
287                 if(m_pFtpConnection->PutFile(localPath.string().c_str(), localPath.leaf().string().c_str(),
288                     FTP_TRANSFER_TYPE_BINARY,0))
289                     std::cout << "上传文件[" << localPath.leaf().string() << "]成功!" << std::endl;
290                 else
291                 {
292                     DWORD dw0 = GetLastError();
293                     if (dw0)
294                     {
295                         char szBuf[512]={0};
296                         DWORD dw = 0;
297                         DWORD dwLen = sizeof(szBuf)-1;
298                         InternetGetLastResponseInfo(&dw, szBuf, &dwLen);
299                         std::cout << "上传文件[" << localPath.leaf().string() << "]失败!ErrCode:" << dw0 << "ErrMsg:" << szBuf << std::endl;
300                         goto __end;
301                     }
302                 }
303             }
304         }
305         else
306         {
307             std::cout << "指定上传文件不存在!" << std::endl;
308             nRet = -1;
309             goto __end;
310         }
311     }
312
313 __end:
314     if (pFtpFileFind != NULL)
315     {
316         pFtpFileFind->Close();
317         delete pFtpFileFind;
318     }
319     this->Close();
320     return nRet;
321 }
322
323 void CFtpClient::CreateDirectory(boost::filesystem::path path)
324 {
325     boost::filesystem::path::iterator itor = path.begin();
326     boost::filesystem::path pathTmp;
327     while(itor != path.end())
328     {
329         pathTmp /= (*itor).string();
330         if (!pathTmp.empty() && !boost::filesystem::exists(pathTmp))
331         {
332             boost::filesystem::create_directory(pathTmp);
333         }
334         ++itor;
335     }
336 }
时间: 2024-08-08 22:10:03

FTP客户端上传下载实现的相关文章

****使用ftp软件上传下载php文件时换行符丢失bug

在使用ftp软件上传下载php源文件时,我们偶尔会发现在本地windows下notepad++编辑器写好的php文件,在使用ftp上传到linux服务器后,php文件的换行符全部丢失了,导致php文件无法正常运行. 这个时候,再次通过ftp软件把刚才上传的php文件下载到本地windows,用notepad++编辑器打开后,发现php源代码变成了一行,换行丢失. 发生这种情况的原因是什么呢?飘易就以一句话概括下:    由于linux下换行是\n,而windows下换行是\r\n,当ftp软件在

FTP文件上传下载及验证

FTP文件上传下载及验证 有时候经常用到FTP的上传下载,本身代码相对比较简单,但有时需要考虑到文件上传下载进行验证.大体思路是上传时将FTP日志重定向到本地文件,再根据FTP返回码进行检查,这样有个缺点就是不能检验文件上传的完整性:下载时利用ls,ll命令查看是否存在. 上传代码 uploadFile() { ftp -i -v -n <<! >/tmp/ftp.log open $FTP_IP $FTP_PORT user $USER_ID $PASSWORD prompt cd $

【FTP】FTP文件上传下载-支持断点续传

Jar包:apache的commons-net包: 支持断点续传 支持进度监控(有时出不来,搞不清原因) 相关知识点 编码格式: UTF-8等; 文件类型: 包括[BINARY_FILE_TYPE(常用)]和[ASCII_FILE_TYPE]两种; 数据连接模式:一般使用LocalPassiveMode模式,因为大部分客户端都在防火墙后面: 1. LocalPassiveMode:服务器端打开数据端口,进行数据传输: 2. LocalActiveMode:客户端打开数据端口,进行数据传输: 系统

ftp文件服务器上传下载案例

Vsftpd是very secure FTP daemon(非常安全的FTP守护进程) 21端口 控制连接 20端口 数据连接 在Linux安装vsftpd后 默认匿名用户与本地用户都可以登录 匿名用户登陆到/var/ftp,不能上传和下载 本地用户登陆到本地用户的家目录,可以上传和下载 Linux  Client(192.168.2.2) -------RHEL5.9(vmnet1)--------(vmnet1) 192.168.2.1                   Win7  Cli

Java通过FTP服务器上传下载文件的解决方案

对于使用文件进行交换数据的应用来说,使用FTP 服务器是一个很不错的解决方案.本文使用Apache Jakarta Commons Net(commons-net-3.3.jar)基于FileZilla Server服务器实现FTP服务器上文件的上传/下载/删除等操作. 关于FileZilla Server服务器的详细搭建配置过程,详情请见FileZilla Server安装配置教程.之前有朋友说,上传大文件(几百M以上的文件)到FTP服务器时会重现无法重命名的问题,但本人亲测上传2G的文件到F

JMeter创建FTP测试服务器上传下载性能

在工作中,有时候我们会对服务器的上传下载性能进行测试,于是就整理了工作中测试ftp上传下载的是实战总结. 测试环境: jmeter 我使用的是apache-jmeter-2.13 测试服务器是阿里云上的真实服务器,IP:***.***.***.*** (为了服务器安全,我就不写那么精确的IP地址了.)但是被测服务器上必须按照ftp服务端,有ftp账号,如果这里不明白可以留言. 1,创建一个线程组 2.线程组--->添加--->配置元件--->FTP请求缺省值. 3.线程组--->添

winform通过FTP协议上传下载文件

上传文件:窗体代码 一次上传多个文件(grdAffixFilesList中需要上传的) private Boolean UploadFile() { string filename; int upCount=0; for (int i = 0; i < this.grdAffixFilesList.Rows.Count; i++) { filename = this.grdAffixFilesList.Rows[i].Cells["FILEPATH"].Text.ToString

Spring中利用组件实现从FTP服务器上传/下载文件

FtpUtil.java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.ne

Java 利用Apache Commons Net 实现 FTP文件上传下载

package woxingwosu; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Comparator;