和上一份簡單 上傳下載一樣
來,任何的方法不懂的,http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html
API拿走不謝!!!
1.FTP配置實體

1 package com.agen.util; 2 3 public class FtpConfig { 4 //主機ip 5 private String FtpHost = "192.168.18.252"; 6 //端口號 7 private int FtpPort = 21; 8 //ftp用戶名 9 private String FtpUser = "ftp"; 10 //ftp密碼 11 private String FtpPassword = "agenbiology"; 12 //ftp中的目錄 這里先指定的根目錄 13 private String FtpPath = "/"; 14 15 16 17 public String getFtpHost() { 18 return FtpHost; 19 } 20 public void setFtpHost(String ftpHost) { 21 FtpHost = ftpHost; 22 } 23 public int getFtpPort() { 24 return FtpPort; 25 } 26 public void setFtpPort(int ftpPort) { 27 FtpPort = ftpPort; 28 } 29 public String getFtpUser() { 30 return FtpUser; 31 } 32 public void setFtpUser(String ftpUser) { 33 FtpUser = ftpUser; 34 } 35 public String getFtpPassword() { 36 return FtpPassword; 37 } 38 public void setFtpPassword(String ftpPassword) { 39 FtpPassword = ftpPassword; 40 } 41 public String getFtpPath() { 42 return FtpPath; 43 } 44 public void setFtpPath(String ftpPath) { 45 FtpPath = ftpPath; 46 } 47 48 49 50 }
2.FTP工具類,僅有一個刪除文件夾【目錄】的操作方法,刪除文件夾包括文件夾下所有的文件

1 package com.agen.util; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.OutputStream; 6 import java.net.URLDecoder; 7 import java.net.URLEncoder; 8 9 import org.apache.commons.net.ftp.FTPClient; 10 import org.apache.commons.net.ftp.FTPFile; 11 12 13 14 public class FtpUtils { 15 16 /** 17 * 獲取FTP連接 18 * @return 19 */ 20 public FTPClient getFTPClient() { 21 FtpConfig config = new FtpConfig(); 22 FTPClient ftpClient = new FTPClient(); 23 boolean result = true; 24 try { 25 //連接FTP服務器 26 ftpClient.connect(config.getFtpHost(), config.getFtpPort()); 27 //如果連接 28 if (ftpClient.isConnected()) { 29 //提供用戶名/密碼登錄FTP服務器 30 boolean flag = ftpClient.login(config.getFtpUser(), config.getFtpPassword()); 31 //如果登錄成功 32 if (flag) { 33 //設置編碼類型為UTF-8 34 ftpClient.setControlEncoding("UTF-8"); 35 //設置文件類型為二進制文件類型 36 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); 37 } else { 38 result = false; 39 } 40 } else { 41 result = false; 42 } 43 //成功連接並 登陸成功 返回連接 44 if (result) { 45 return ftpClient; 46 } else { 47 return null; 48 } 49 } catch (Exception e) { 50 e.printStackTrace(); 51 return null; 52 } 53 } 54 /** 55 * 刪除文件夾下所有文件 56 * @return 57 * @throws IOException 58 */ 59 public boolean deleteFiles(String pathname) throws IOException{ 60 FTPClient ftpClient = getFTPClient(); 61 ftpClient.enterLocalPassiveMode();//在調用listFiles()方法之前需要調用此方法 62 FTPFile[] ftpFiles = ftpClient.listFiles(new String((pathname).getBytes("UTF-8"),"iso-8859-1")); 63 System.out.println(ftpFiles == null ? null :ftpFiles.length ); 64 if(ftpFiles.length > 0){ 65 for (int i = 0; i < ftpFiles.length; i++) { 66 System.out.println(ftpFiles[i].getName()); 67 if(ftpFiles[i].isDirectory()){ 68 deleteFiles(pathname+"/"+ftpFiles[i].getName()); 69 }else{ 70 System.out.println(pathname); 71 //這里需要提供刪除文件的路徑名 才能刪除文件 72 ftpClient.deleteFile(new String((pathname+"/"+ftpFiles[i].getName()).getBytes("UTF-8"),"iso-8859-1")); 73 FTPFile [] ftFiles = ftpClient.listFiles(new String((pathname).getBytes("UTF-8"),"iso-8859-1")); 74 if(ftFiles.length == 0){//如果文件夾中現在已經為空了 75 ftpClient.removeDirectory(new String(pathname.getBytes("UTF-8"),"iso-8859-1")); 76 } 77 } 78 } 79 } 80 return true; 81 } 82 83 /** 84 * 關閉 輸入流或輸出流 85 * @param in 86 * @param out 87 * @param ftpClient 88 */ 89 public void close(InputStream in, OutputStream out,FTPClient ftpClient) { 90 if (null != in) { 91 try { 92 in.close(); 93 } catch (IOException e) { 94 e.printStackTrace(); 95 System.out.println("輸入流關閉失敗"); 96 } 97 } 98 if (null != out) { 99 try { 100 out.close(); 101 } catch (IOException e) { 102 e.printStackTrace(); 103 System.out.println("輸出流關閉失敗"); 104 } 105 } 106 if (null != ftpClient) { 107 try { 108 ftpClient.logout(); 109 ftpClient.disconnect(); 110 } catch (IOException e) { 111 e.printStackTrace(); 112 System.out.println("Ftp服務關閉失敗!"); 113 } 114 } 115 } 116 117 }
刪除方法中,調用listFiles()方法之前,需要調用ftpClient.enterLocalPassiveMode();
關於調用listFiles()方法,有以下幾種情況需要注意:
①listFiles()方法可能返回為null,這個問題我也遇到了,這種原因是因為FTP服務器的語言環境,編碼方式,時間戳等各種的沒有處理好或者與程序端並不一致
②首先可以使用listNames()方法排除是否是路徑的原因,路徑編碼方式等原因
③其次,調整好路徑后,有如下提示的錯誤Caused by: java.lang.ClassNotFoundException: org.apache.oro.text.regex.MalformedPatternException,需要導入一個架包 【jakarta-oro-2.0.8.jar】
3.實際用到的FTP上傳【創建多層中文目錄】+下載【瀏覽器下載OR服務器下載】+刪除 【處理FTP編碼方式與本地編碼不一致】

1 /** 2 * 上傳至FTP服務器 3 * @param partFile 4 * @param request 5 * @param diseaseName 6 * @param productName 7 * @param diseaseId 8 * @return 9 * @throws IOException 10 */ 11 @RequestMapping("/uploadFiles") 12 @ResponseBody 13 public boolean uploadFiles(@RequestParam("upfile")MultipartFile partFile,HttpServletRequest request,String diseaseName,String productName,String diseaseId) throws IOException{ 14 Disease disease = new Disease(); 15 disease.setDiseaseId(diseaseId); 16 Criteria criteria = getCurrentSession().createCriteria(Filelist.class); 17 criteria.add(Restrictions.eq("disease", disease)); 18 Filelist flFilelist = filelistService.uniqueResult(criteria); 19 if(flFilelist == null){ 20 FtpUtils ftpUtils = new FtpUtils(); 21 boolean result = true; 22 InputStream in = null; 23 FTPClient ftpClient = ftpUtils.getFTPClient(); 24 if (null == ftpClient) { 25 System.out.println("FTP服務器未連接成功!!!"); 26 return false; 27 } 28 try { 29 30 String path = "/file-ave/"; 31 ftpClient.changeWorkingDirectory(path); 32 System.out.println(ftpClient.printWorkingDirectory()); 33 //創建產品文件夾 轉碼 防止在FTP服務器上創建時亂碼 34 ftpClient.makeDirectory(new String(productName.getBytes("UTF-8"),"iso-8859-1")); 35 //指定當前的工作路徑到產品文件夾下 36 ftpClient.changeWorkingDirectory(path+new String(productName.getBytes("UTF-8"),"iso-8859-1")); 37 //創建疾病文件夾 轉碼 38 ftpClient.makeDirectory(new String(diseaseName.getBytes("UTF-8"),"iso-8859-1")); 39 //指定當前的工作路徑到疾病文件夾下 40 ftpClient.changeWorkingDirectory(path+new String(productName.getBytes("UTF-8"),"iso-8859-1")+"/"+new String(diseaseName.getBytes("UTF-8"),"iso-8859-1")); 41 42 // 得到上傳的文件的文件名 43 String filename = partFile.getOriginalFilename(); 44 in = partFile.getInputStream(); 45 ftpClient.storeFile(new String(filename.getBytes("UTF-8"),"iso-8859-1"), in); 46 path += productName+"/"+diseaseName+"/"; 47 48 49 DecimalFormat df = new DecimalFormat(); 50 String fileSize = partFile.getSize()/1024>100 ? (partFile.getSize()/1024/1024>100? df.format((double)partFile.getSize()/1024/1024/1024)+"GB" :df.format((double)partFile.getSize()/1024/1024)+"MB" ) :df.format((double)partFile.getSize()/1024)+"KB"; 51 HttpSession session = request.getSession(); 52 User user = (User) session.getAttribute("user"); 53 54 Filelist filelist = new Filelist(); 55 filelist.setFileId(UUID.randomUUID().toString()); 56 filelist.setFileName(filename); 57 filelist.setFilePath(path+filename); 58 filelist.setFileCre(fileSize); 59 filelist.setCreateDate(new Timestamp(System.currentTimeMillis())); 60 filelist.setUpdateDate(new Timestamp(System.currentTimeMillis())); 61 filelist.setTransPerson(user.getUserId()); 62 filelist.setDisease(disease); 63 filelistService.save(filelist); 64 65 66 67 return result; 68 69 } catch (IOException e) { 70 e.printStackTrace(); 71 return false; 72 } finally { 73 ftpUtils.close(in, null, ftpClient); 74 } 75 }else{ 76 return false; 77 } 78 } 79 80 /** 81 * 刪除文件 82 * @param filelistId 83 * @return 84 * @throws IOException 85 * @throws UnsupportedEncodingException 86 */ 87 @RequestMapping("/filelistDelete") 88 @ResponseBody 89 public boolean filelistDelete(String []filelistId) throws UnsupportedEncodingException, IOException{ 90 for (String string : filelistId) { 91 Filelist filelist = filelistService.uniqueResult("fileId", string); 92 String filePath = filelist.getFilePath(); 93 FtpUtils ftpUtils = new FtpUtils(); 94 FTPClient ftpClient = ftpUtils.getFTPClient(); 95 InputStream inputStream = ftpClient.retrieveFileStream(new String(filePath.getBytes("UTF-8"),"iso-8859-1")); 96 if(inputStream != null || ftpClient.getReplyCode() == 550){ 97 ftpClient.deleteFile(filePath); 98 } 99 filelistService.deleteById(string); 100 } 101 return true; 102 } 103 104 /** 105 * 下載到本地 106 * @param fileId 107 * @param response 108 * @return 109 * @throws IOException 110 * @throws InterruptedException 111 */ 112 @RequestMapping("/fileDownload") 113 public String fileDownload(String fileId,HttpServletResponse response) throws IOException, InterruptedException{ 114 Filelist filelist = filelistService.get(fileId); 115 Assert.notNull(filelist); 116 String filePath = filelist.getFilePath(); 117 String fileName = filelist.getFileName(); 118 String targetPath = "D:/biologyInfo/Download/"; 119 File file = new File(targetPath); 120 while(!file.exists()){ 121 file.mkdirs(); 122 } 123 FtpUtils ftpUtils = new FtpUtils(); 124 FileOutputStream out = null; 125 FTPClient ftpClient = ftpUtils.getFTPClient(); 126 if (null == ftpClient) { 127 System.out.println("FTP服務器未連接成功!!!"); 128 } 129 try { 130 //下載到 應用服務器而不是本地 131 // //要寫到本地的位置 132 // File file2 = new File(targetPath + fileName); 133 // out = new FileOutputStream(file2); 134 // //截取文件的存儲位置 不包括文件本身 135 // filePath = filePath.substring(0, filePath.lastIndexOf("/")); 136 // //文件存儲在FTP的位置 137 // ftpClient.changeWorkingDirectory(new String(filePath.getBytes("UTF-8"),"iso-8859-1")); 138 // System.out.println(ftpClient.printWorkingDirectory()); 139 // //下載文件 140 // ftpClient.retrieveFile(new String(fileName.getBytes("UTF-8"),"iso-8859-1"), out); 141 // return true; 142 143 //下載到 客戶端 瀏覽器 144 InputStream inputStream = ftpClient.retrieveFileStream(new String(filePath.getBytes("UTF-8"),"iso-8859-1")); 145 response.setContentType("multipart/form-data"); 146 response.setHeader("Content-Disposition", "attachment;filename="+ new String(fileName.getBytes("UTF-8"),"iso-8859-1")); 147 OutputStream outputStream = response.getOutputStream(); 148 byte[] b = new byte[1024]; 149 int length = 0; 150 while ((length = inputStream.read(b)) != -1) { 151 outputStream.write(b, 0, length); 152 } 153 154 } catch (IOException e) { 155 e.printStackTrace(); 156 } finally { 157 ftpUtils.close(null, out, ftpClient); 158 } 159 return null; 160 } 161
最后注意一點:
FTP服務器不一樣,會引發很多的問題,因為FTP服務器的語言環境,編碼方式,時間戳等各種的原因,導致程序中需要進行大量的類似的處理,要跟FTP進行匹配使用。
因為FTP架包是apache的,所以使用apache自己的FTP服務器,是匹配度最高的,傳入文件路徑等都不需要考慮轉碼等各種各樣的問題!!!
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------附錄------------------------------------------------------------------------------------
FTPFile[] ftpFiles = ftpClient.listFiles(new String((pathname).getBytes("UTF-8"),"iso-8859-1"));
方法的調用,報錯如下:

1 java.lang.NoClassDefFoundError: org/apache/oro/text/regex/MalformedPatternException 2 at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createUnixFTPEntryParser(DefaultFTPFileEntryParserFactory.java:169) 3 at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createFileEntryParser(DefaultFTPFileEntryParserFactory.java:94) 4 at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:2358) 5 at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2141) 6 at com.sxd.ftp.FtpUtils.deleteFiles(FtpUtils.java:170) 7 at com.sxd.ftp.FtpUtils.test(FtpUtils.java:200) 8 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 9 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 10 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 11 at java.lang.reflect.Method.invoke(Unknown Source) 12 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 13 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 14 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 15 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 16 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 17 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 18 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 19 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 20 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 21 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 22 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 23 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 24 at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 25 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 26 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 27 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 28 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 29 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 30 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 31 Caused by: java.lang.ClassNotFoundException: org.apache.oro.text.regex.MalformedPatternException 32 at java.net.URLClassLoader.findClass(Unknown Source) 33 at java.lang.ClassLoader.loadClass(Unknown Source) 34 at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 35 at java.lang.ClassLoader.loadClass(Unknown Source) 36 ... 29 more
解決方法:
jakarta-oro-2.0.8.jar