【FTP】org.apache.commons.net.ftp.FTPClient实现复杂的上传下载,操作目录,处理编码...

和上一份简单 上传下载一样

来,任何的方法不懂的,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 }
View Code

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 }
View Code

删除方法中,调用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      
View Code

 

 

最后注意一点:

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
View Code

解决方法:
jakarta-oro-2.0.8.jar

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误通常出现在你的 Java 项目中使用了 Apache Commons Net 库,但是该库没有被正确地添加到类路径中。你需要在项目中添加正确版本的 Apache Commons Net 库。 如果你使用 Maven 进行依赖管理,可以在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.7.2</version> </dependency> ``` 如果你手动管理依赖,可以下载适当版本的 Apache Commons Net 库,并将其添加到类路径中。 如果你已经添加了正确的库但仍然遇到此错误,请确保你的构建工具(例如 Maven 或 Gradle)正在正确地构建项目,并且库已被正确地包含在项目中。 ### 回答2: java.lang.NoClassDefFoundError: org.apache.commons.net.ftp.FTPClient是一个Java异常,表示找不到org.apache.commons.net.ftp.FTPClient类。 这个错误通常发生在类加载器不能在运行时找到所需的类文件时。在这种情况下,出现了一个或多个可能的原因: 1. 缺少依赖项:发生这个错误最常见的原因是缺少所需的依赖项。在这种情况下,你需要确保你的项目中包含了Apache Commons Net库的JAR文件。你可以通过将该库添加到项目的构建路径中来解决此问题。 2. 类路径问题:如果你已经添加了正确的依赖项但仍然发生此错误,可能是由于类路径设置不正确造成的。请确保你的类路径包括了包含所需类文件的路径。 3. 版本不匹配:有时候,当你使用的类库的版本与你项目中的其他依赖项不兼容时,会发生NoClassDefFoundError错误。在这种情况下,你需要确保你所使用的类库的版本与其他依赖项相匹配。 解决这个错误的步骤如下: 1. 检查你的项目中是否包含了正确的依赖项。 2. 确保你的类路径设置正确并且包含了所有必要的类文件。 3. 检查你项目中所有依赖项的版本是否匹配。 如果你按照上述步骤操作仍然无法解决问题,你可以尝试在互联网上搜索更多关于该错误的解决方案或者咨询开发社区的帮助。 ### 回答3: java.lang.NoClassDefFoundError: org.apache.commons.net.ftp.FTPClientJava中的一个异常错误,表示找不到org.apache.commons.net.ftp.FTPClient类。 在Java开发中,这个错误通常是由于缺少相关的jar包或类路径配置错误引起的。解决这个错误的方法包括: 1. 确保你的项目中包含了org.apache.commons.net.ftp.FTPClient类所在的jar包。这个类通常位于Apache Commons Net库中,你需要将这个jar包添加到你的项目的构建路径中。 2. 检查你的类路径配置是否正确。如果你使用的是Eclipse等IDE,你可以确认你的项目构建路径中包含了Apache Commons Net库。 3. 如果你已经正确导入了jar包并配置了类路径,但仍然出现这个错误,你可以检查一下jar包是否被正确部署到了服务器或者运行环境中。 总而言之,解决java.lang.NoClassDefFoundError: org.apache.commons.net.ftp.FTPClient错误的方法是确保项目中包含了所需的jar包,并配置了正确的类路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值