和上一份简单 上传下载一样
来,任何的方法不懂的,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