FTP工具类开发

    正所谓工欲善其事必先利其器,熟悉了下一套流程,以此铭记。

    1.FTP服务搭建

        由于本人使用wondiow系统,所以针对window的童鞋们可以查看。至于windowX这里配置类似,所以不要纠结于window系统不同。经过以上操作我们可以获取到ftp的用户名,密码,以及IP地址,端口号(ps:默认端口号,搭建时可以设置)

    2.FTP编码集问题

         由于FTP使用编码集为ISO-8859-1,所以在中文文件夹以及文件名称上传,获取服务器文件等会出现问题。有以下2中解决方案:

             1.将目录、文件转码,这样就造成跟目录、文件相关的都要转码,以至于

 

      ftpClient.changeWorkingDirectory(new String(onepath.getBytes("GBK"),"iso-8859-1"));
      ftpClient.storeFile(new String(fileName.getBytes("GBK"),"iso-8859-1"), in);
      ftpClient.listFiles(new String(remotePath.getBytes("GBK"),"iso-8859-1"));

                 那这样岂不是很麻烦,而且每次使用都需要转码,有没有更简单的呢?有,请看第2中

              2.设置相应编码集等信息

      ftpClient = new FTPClient();
      ftpClient.setControlEncoding("GBK");
      FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);//系统类型   这表示window系统
      conf.setServerLanguageCode("zh"); 
      ftpClient.configure(conf);
      ftpClient.connect(this.ip, this.port);

               这边需要注意的是顺序必须这么写

    3.工具类相关

            1.Jar包问题

                 由于本人使用maven,pom中的配置

      <dependency>
      <groupId>commons-net</groupId>
       <artifactId>commons-net</artifactId>
      <version>3.5</version>
       <classifier>ftp</classifier>
      </dependency>

            2.工具类开发

 

  1 import org.apache.commons.net.ftp.*;
  2 import org.slf4j.Logger;
  3 import org.slf4j.LoggerFactory;
  4 
  5 import java.io.*;
  6 import java.util.Arrays;
  7 import java.util.List;
  8 
  9 /**
 10  * FTP上传工具类
 11  */
 12 public class FtpUtil {
 13     private static Logger log = LoggerFactory.getLogger(FtpUtil.class);
 14     private final static String FILE_SEPARATOR = System.getProperties().getProperty("file.separator");
 15     private String ip;
 16     private String username;
 17     private String password;
 18     private int port = 21;
 19     private FTPClient ftpClient = null;
 20 
 21     public FtpUtil(String serverIP, String username, String password) {
 22         this.ip = serverIP;
 23         this.username = username;
 24         this.password = password;
 25     }
 26 
 27     public FtpUtil(String serverIP, int port, String username, String password) {
 28         this.ip = serverIP;
 29         this.username = username;
 30         this.password = password;
 31         this.port = port;
 32     }
 33 
 34     /**
 35      * 连接ftp服务器
 36      */
 37     public boolean connectServer() {
 38         boolean result = true;
 39         try {
 40             ftpClient = new FTPClient();
 41             ftpClient.setControlEncoding("GBK");
 42             FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
 43             conf.setServerLanguageCode("zh");
 44             ftpClient.configure(conf);
 45             ftpClient.connect(this.ip, this.port);
 46             ftpClient.login(this.username, this.password);
 47             ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
 48             int reply = ftpClient.getReplyCode();
 49             if (!FTPReply.isPositiveCompletion(reply)) {
 50                 ftpClient.disconnect();
 51                 result = false;
 52             }
 53         } catch (IOException e) {
 54             e.printStackTrace();
 55             log.error("连接ftp服务器失败", e);
 56             result = false;
 57         }
 58         return result;
 59     }
 60 
 61     /**
 62      * 断开与ftp服务器连接
 63      */
 64     public boolean closeServer() {
 65         try {
 66             if (ftpClient != null && ftpClient.isConnected()) {
 67                 ftpClient.logout();
 68                 ftpClient.disconnect();
 69             }
 70             return true;
 71         } catch (IOException e) {
 72             log.error("断开与ftp服务器连接失败", e);
 73             return false;
 74         }
 75     }
 76 
 77     /**
 78      * 向FTP根目录上传文件
 79      *
 80      * @param localFile
 81      * @param newName   文件名称
 82      * @throws Exception
 83      */
 84     public boolean uploadFile(String localFile, String newName) {
 85         boolean success = false;
 86         InputStream input = null;
 87         try {
 88             File file = null;
 89             if (checkFileExist(localFile)) {
 90                 file = new File(localFile);
 91             }
 92             input = new FileInputStream(file);
 93             success = ftpClient.storeFile(newName, input);
 94         } catch (Exception e) {
 95             log.error("FTP根目录上传文件上传失败(ps:传入文件名)", e);
 96         } finally {
 97             if (input != null) {
 98                 try {
 99                     input.close();
100                 } catch (IOException e) {
101                     e.printStackTrace();
102                     log.error("FTP根目录上传文件上传(ps:传入文件名),输入流关闭失败", e);
103                 }
104             }
105         }
106         return success;
107     }
108 
109     /**
110      * 向FTP根目录上传文件
111      *
112      * @param input
113      * @param newName 新文件名
114      * @throws Exception
115      */
116     public boolean uploadFile(InputStream input, String newName) {
117         boolean success = false;
118         try {
119             success = ftpClient.storeFile(newName, input);
120         } catch (Exception e) {
121             log.error("FTP根目录上传文件上传失败(ps:传入文件流)", e);
122         } finally {
123             if (input != null) {
124                 try {
125                     input.close();
126                 } catch (IOException e) {
127                     e.printStackTrace();
128                     log.error("FTP根目录上传文件上传(ps:传入文件流),输入流关闭失败", e);
129                 }
130             }
131         }
132         return success;
133     }
134 
135     /**
136      * 向FTP指定路径上传文件
137      *
138      * @param localFile
139      * @param newName        新文件名
140      * @param remoteFoldPath
141      * @throws Exception
142      */
143     public boolean uploadFile(String localFile, String newName, String remoteFoldPath) {
144         InputStream input = null;
145         boolean success = false;
146         try {
147             // 改变当前路径到指定路径
148             if (!this.changeDirectory(remoteFoldPath)) {
149                 return false;
150             }
151             File file = null;
152             if (checkFileExist(localFile)) {
153                 file = new File(localFile);
154             }
155             input = new FileInputStream(file);
156             success = ftpClient.storeFile(newName, input);
157         } catch (Exception e) {
158             log.error("FTP指定路径上传文件失败(ps:本地文件路径以及ftp服务器中文件名)", e);
159         } finally {
160             if (input != null) {
161                 try {
162                     input.close();
163                 } catch (IOException e) {
164                     e.printStackTrace();
165                     log.error("FTP指定路径上传文件失败(ps:本地文件路径以及ftp服务器中文件名),输入流关闭失败", e);
166                 }
167             }
168         }
169         return success;
170     }
171 
172     /**
173      * 向FTP指定路径上传文件
174      *
175      * @param input
176      * @param newName        新文件名
177      * @param remoteFoldPath
178      * @throws Exception
179      */
180     public boolean uploadFile(InputStream input, String newName, String remoteFoldPath) throws Exception {
181         boolean success = false;
182         try {
183             // 改变当前路径到指定路径
184             if (!this.changeDirectory(remoteFoldPath)) {
185                 return false;
186             }
187             success = ftpClient.storeFile(newName, input);
188         } catch (Exception e) {
189             log.error("FTP指定路径上传文件失败(ps:本地文件流及ftp服务器中文件名)", e);
190         } finally {
191             if (input != null) {
192                 try {
193                     input.close();
194                 } catch (IOException e) {
195                     log.error("FTP指定路径上传文件失败(ps:本地文件流及ftp服务器中文件名),输入流关闭失败", e);
196                 }
197             }
198         }
199         return success;
200     }
201 
202     /**
203      * 从FTP服务器下载文件
204      *
205      * @param remotePath FTP路径(不包含文件名)
206      * @param fileName   下载文件名
207      * @param localPath  本地路径
208      */
209     public boolean downloadFile(String remotePath, String fileName, String localPath) {
210         BufferedOutputStream output = null;
211         boolean success = false;
212         try {
213             // 检查本地路径
214             if (!this.checkFileExist(localPath)) {
215                 return false;
216             }
217             // 改变工作路径
218             if (!this.changeDirectory(remotePath)) {
219                 return false;
220             }
221             // 列出当前工作路径下的文件列表
222             List<FTPFile> fileList = this.getFileList();
223             if (fileList == null || fileList.size() == 0) {
224                 return false;
225             }
226             for (FTPFile ftpfile : fileList) {
227                 if (ftpfile.getName().equals(fileName)) {
228                     File localFilePath = new File(localPath + File.separator + ftpfile.getName());
229                     output = new BufferedOutputStream(new FileOutputStream(localFilePath));
230                     success = ftpClient.retrieveFile(ftpfile.getName(), output);
231                 }
232             }
233         } catch (Exception e) {
234             log.error("FTP服务器下载文件失败", e);
235         } finally {
236             if (output != null) {
237                 try {
238                     output.close();
239                 } catch (IOException e) {
240                     log.error("FTP服务器下载文件,输出流关闭失败", e);
241                 }
242             }
243         }
244         return success;
245     }
246 
247     /**
248      * 从FTP服务器获取文件流
249      *
250      * @param remoteFilePath
251      * @return
252      * @throws Exception
253      */
254     public InputStream downloadFile(String remoteFilePath) {
255         try {
256             return ftpClient.retrieveFileStream(remoteFilePath);
257         } catch (IOException e) {
258             log.error("FTP服务器获取文件流失败", e);
259         }
260         return null;
261     }
262 
263     /**
264      * 获取FTP服务器上[指定路径]下的文件列表
265      *
266      * @param remotePath
267      * @return
268      */
269     public List<FTPFile> getFtpServerFileList(String remotePath) {
270         try {
271             FTPListParseEngine engine = ftpClient.initiateListParsing(remotePath);
272             return Arrays.asList(engine.getNext(25));
273         } catch (IOException e) {
274             log.error("获取FTP服务器上[指定路径]下的文件列表(getFtpServerFileList)失败", e);
275         }
276         return null;
277     }
278 
279     /**
280      * 获取FTP服务器上[指定路径]下的文件列表
281      *
282      * @param remotePath
283      * @return
284      */
285     public List<FTPFile> getFileList(String remotePath) {
286         List<FTPFile> ftpfiles = null;
287         try {
288             ftpfiles = Arrays.asList(ftpClient.listFiles(remotePath));
289         } catch (IOException e) {
290             log.error("获取FTP服务器上[指定路径]下的文件列表(getFileList)失败", e);
291         }
292         return ftpfiles;
293     }
294 
295     /**
296      * 获取FTP服务器[当前工作路径]下的文件列表
297      *
298      * @return
299      */
300     public List<FTPFile> getFileList() {
301         List<FTPFile> ftpfiles = null;
302         try {
303             ftpfiles = Arrays.asList(ftpClient.listFiles());
304         } catch (IOException e) {
305             log.error("获取FTP服务器[当前工作路径]下的文件列表失败", e);
306         }
307         return ftpfiles;
308     }
309 
310     /**
311      * 改变FTP服务器工作路径
312      *
313      * @param remoteFoldPath
314      */
315     public boolean changeDirectory(String remoteFoldPath) {
316         boolean result = false;
317         try {
318             result = ftpClient.changeWorkingDirectory(new String(remoteFoldPath));
319         } catch (IOException e) {
320             log.error("改变FTP服务器工作路径失败", e);
321         }
322         return result;
323     }
324 
325     /**
326      * 删除文件
327      *
328      * @param remoteFilePath
329      * @return
330      * @throws Exception
331      */
332     public boolean deleteFtpServerFile(String remoteFilePath) {
333         boolean result = false;
334         try {
335             result = ftpClient.deleteFile(remoteFilePath);
336         } catch (IOException e) {
337             log.error("FTP服务器删除文件失败", e);
338         }
339         return result;
340     }
341 
342     /**
343      * 删除目录
344      *
345      * @param remoteFoldPath
346      * @return
347      * @throws Exception
348      */
349     public boolean deleteFold(String remoteFoldPath) {
350         boolean result = false;
351         try {
352             result = ftpClient.removeDirectory(remoteFoldPath);
353         } catch (IOException e) {
354             log.error("FTP服务器删除目录失败", e);
355         }
356         return result;
357     }
358 
359     /**
360      * 删除目录以及文件
361      *
362      * @param remoteFoldPath
363      * @return
364      */
365     public boolean deleteFoldAndsubFiles(String remoteFoldPath) {
366         boolean success = false;
367         List<FTPFile> list = this.getFileList(remoteFoldPath);
368         if (list == null || list.size() == 0) {
369             return deleteFold(remoteFoldPath);
370         }
371         for (FTPFile ftpFile : list) {
372             String name = ftpFile.getName();
373             if (ftpFile.isDirectory()) {
374                 success = deleteFoldAndsubFiles(remoteFoldPath + FILE_SEPARATOR + name);
375             } else {
376                 success = deleteFtpServerFile(remoteFoldPath + FILE_SEPARATOR + name);
377             }
378             if (!success) {
379                 break;
380             }
381         }
382         if (!success) {
383             return false;
384         }
385         success = deleteFold(remoteFoldPath);
386         return success;
387     }
388 
389     /**
390      * 创建目录
391      *
392      * @param remoteFoldPath
393      * @return
394      */
395     public boolean createFold(String remoteFoldPath) {
396         boolean result = false;
397         try {
398             result = ftpClient.makeDirectory(remoteFoldPath);
399         } catch (IOException e) {
400             log.error("FTP服务器创建目录失败", e);
401         }
402         return result;
403     }
404 
405 
406     /**
407      * 检查本地路径是否存在
408      *
409      * @param filePath
410      * @return
411      * @throws Exception
412      */
413     public boolean checkFileExist(String filePath) {
414         return new File(filePath).exists();
415     }
416 
417     /**
418      * 把文件移动到特定目录下
419      *
420      * @param remoteFile
421      * @param remoteNewPath
422      * @return
423      */
424     public boolean moveFtpServerFile(String remoteFile, String remoteNewPath) {
425         boolean result = false;
426         try {
427             result = ftpClient.rename(remoteFile, remoteNewPath);
428         } catch (IOException e) {
429             log.error("FTP服务器文件移动失败", e);
430         }
431         return result;
432     }
433 
434     /**
435      * 判断是文件还是目录
436      *
437      * @param remoteOldPath
438      * @return
439      */
440     public boolean isContents(String remoteOldPath) {
441         return changeDirectory(remoteOldPath);
442     }
443 
444     /**
445      * 递归创建远程服务器目录
446      *
447      * @param dirpath 远程服务器文件绝对路径
448      * @return 目录创建是否成功
449      */
450     public void createDirecroty(String dirpath) {
451         String directory = dirpath.substring(0, dirpath.lastIndexOf("/") + 1);
452         try {
453             if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(new String(directory))) {
454                 // 如果远程目录不存在,则递归创建远程服务器目录
455                 int start = 0;
456                 int end = 0;
457                 if (directory.startsWith("/")) {
458                     start = 1;
459                 } else {
460                     start = 0;
461                 }
462                 end = directory.indexOf("/", start);
463                 while (true) {
464                     String subDirectory = new String(dirpath.substring(start, end));
465                     if (!ftpClient.changeWorkingDirectory(subDirectory)) {
466                         if (ftpClient.makeDirectory(subDirectory)) {
467                             ftpClient.changeWorkingDirectory(subDirectory);
468                         }
469                     }
470                     start = end + 1;
471                     end = directory.indexOf("/", start);
472                     // 检查所有目录是否创建完毕
473                     if (end <= start) {
474                         break;
475                     }
476                 }
477             }
478         } catch (IOException e) {
479             log.error("递归生成目录失败", e);
480         }
481     }
482 
483 
484     /**
485      * 复制
486      *
487      * @param remoteOldPath
488      * @param remoteNewPath
489      * @return
490      */
491     public boolean copyFtpServerFile(String remoteOldPath, String remoteNewPath) {
492         boolean copyFalg = false;
493         List<FTPFile> filelist;
494         try {
495             ftpClient.enterLocalPassiveMode();
496             filelist = this.getFileList(remoteOldPath);
497             int length = filelist == null || filelist.isEmpty() ? 0 : filelist.size();
498             String category = null;
499             ByteArrayOutputStream fos = null;
500             ByteArrayInputStream in = null;
501             if (length > 0) {
502                 boolean flage = false;
503                 if (this.isContents(remoteOldPath)) {
504                     flage = true;
505                 }
506                 changeDirectory("/");
507                 for (FTPFile ftpFile : filelist) {
508                     category = ftpFile.getName();
509                     if (ftpFile.isFile()) {
510                         // 如果是文件则复制文件
511                         ftpClient.setBufferSize(1024);
512                         fos = new ByteArrayOutputStream();
513                         copyFalg = ftpClient.retrieveFile(flage ? remoteOldPath + FILE_SEPARATOR + category : remoteOldPath, fos);
514                         if (!copyFalg) {
515                             return copyFalg;
516                         }
517                         // 如果读取的文件流不为空则复制文件
518                         if (fos != null) {
519                             in = new ByteArrayInputStream(fos.toByteArray());
520                             copyFalg = ftpClient.storeFile(remoteNewPath + FILE_SEPARATOR + category, in);
521                             // 关闭文件流
522                             fos.close();
523                             in.close();
524                             if (!copyFalg) {
525                                 return copyFalg;
526                             }
527                         }
528                     } else if (ftpFile.isDirectory()) {
529                         // 如果是目录则先创建该目录
530                         copyFalg = this.createFold(remoteNewPath + FILE_SEPARATOR + category);
531                         // 再进入子目录进行递归复制
532                         copyFtpServerFile(remoteOldPath + FILE_SEPARATOR + category, remoteNewPath + FILE_SEPARATOR + category);
533                     }
534                 }
535             }
536         } catch (IOException e) {
537             log.error("文件复制失败", e);
538             copyFalg = false;
539         }
540         return copyFalg;
541     }
542 
543     public static void main(String[] args) {
544         FtpUtil ftpUtil = new FtpUtil("", "", "");
545         //执行文件移动
546         /*if (ftpUtil.connectServer()) {
547             if (ftpUtil.changeDirectory("load")) {
548                 ftpUtil.moveFtpServerFile("xlsj_h1_v0.7.apk", ".." + FILE_SEPARATOR + "down" + FILE_SEPARATOR + "1.apk");
549                 ftpUtil.closeServer();
550             }
551         }*/
552         //复制  xlsj_h1_v0.8.apk是目录   xlsj_h1_v0.7.apk是文件
553        /* if (ftpUtil.connectServer()) {
554             ftpUtil.copyFtpServerFile("load/xlsj_h1_v0.8.apk", "down");
555             ftpUtil.copyFtpServerFile("load/xlsj_h1_v0.8.apk/xlsj_h1_v0.7.apk", "down");
556             ftpUtil.closeServer();
557         }*/
558 
559         if (ftpUtil.connectServer()) {
560             ftpUtil.copyFtpServerFile("load/安卓上传包/安卓开发包.apk", "down");
561             ftpUtil.closeServer();
562         }
563     }
564 }
View Code

 

 

 参考:

  http://blog.csdn.net/iheng_scau/article/details/41682511

  http://blog.163.com/biangji_and/blog/static/3382923020102491050525/

  http://bbs.csdn.net/topics/390373219

  http://commons.apache.org/proper/commons-net/javadocs/api-1.4.1/org/apache/commons/net/ftp/FTPClient.html

  http://yangyangmyself.iteye.com/blog/1299997

 

 

   

posted @ 2016-07-22 13:13  ╰︶赖床专业户こ  阅读(611)  评论(1编辑  收藏  举报