首页 > 技术文章 > FTP上传、下载文件Demo

YJzhiqianni 2019-11-07 18:47 原文

前言:最近在做一个app,负责写后台接口,客户那边给了一个FTP的账号密码过来,服务器上面放了一堆的PDF文件,让我们这边自己从上面拿,项目是spriongboot的,做个记录供以后参考。


 

 

一、application.yml文件里面配置FTP的相关参数,以便于后面更改相关参数,而不用去改具体的方法参数

ftp:
  #FTP的地址
  ftpHost: 192.168.42.18
  #FTP的端口
  ftpPort: 21
  #连接FTP的账号
  ftpUserName: ****
  #账号密码
  ftpPassword: ****
  #访问FTP的路径
  ftpRemotePath: /
  #本地下载路径
  ftpLocalPath: D:/

 

二、准备一个工具类,用于从application.yml文件读取FTP的相关配置

  1 package com.example.springboot.utils;
  2 
  3 import org.slf4j.Logger;
  4 import org.slf4j.LoggerFactory;
  5 import org.yaml.snakeyaml.Yaml;
  6 
  7 import java.io.*;
  8 import java.util.HashMap;
  9 import java.util.Map;
 10 
 11 import static java.util.Objects.isNull;
 12 
 13 /**
 14  * 工具类,从application.yml获取ftp相关参数
 15  *
 16  * @Author: yaodengyan
 17  * @Date: 2019/11/7
 18  * @Version: 1.0
 19  */
 20 public class YmlUtils {
 21     private static final Logger log = LoggerFactory.getLogger(YmlUtils.class);
 22 
 23     private static String NAME = "application.yml";
 24 
 25     /** 空字符串 */
 26     private static final String NULLSTR = "";
 27 
 28     /**
 29      * 当前对象实例
 30      */
 31     private static YmlUtils ymlUtils;
 32 
 33     /**
 34      * 保存全局属性值
 35      */
 36     private static Map<String, String> map = new HashMap<String, String>();
 37 
 38     private YmlUtils()
 39     {
 40     }
 41 
 42     /**
 43      * 静态工厂方法
 44      */
 45     public static synchronized YmlUtils getInstance()
 46     {
 47         if (ymlUtils == null)
 48         {
 49             ymlUtils = new YmlUtils();
 50         }
 51         return ymlUtils;
 52     }
 53 
 54     /**
 55      * 获取配置
 56      */
 57     public static String getConfig(String key)
 58     {
 59         String value = map.get(key);
 60         if (value == null)
 61         {
 62             Map<?, ?> yamlMap = null;
 63             yamlMap = loadYaml(NAME);
 64             value = String.valueOf(getProperty(yamlMap, key));
 65             map.put(key, value != null ? value : "");
 66         }
 67         return value;
 68     }
 69 
 70     public static Map<?, ?> loadYaml(String fileName)
 71     {
 72         InputStream in = YmlUtils.class.getClassLoader().getResourceAsStream(fileName);
 73         if(isEmpty(fileName)){
 74             return null;
 75         }else {
 76 
 77             return new Yaml().load(in);
 78         }
 79     }
 80 
 81     /**
 82      * * 判断一个字符串是否为非空串
 83      *
 84      * @param str String
 85      * @return true:非空串 false:空串
 86      */
 87     public static boolean isEmpty(String str)
 88     {
 89         Boolean flag = isNull(str) || NULLSTR.equals(str.trim());
 90         return flag;
 91     }
 92 
 93     public static Object getProperty(Map<?, ?> map, Object qualifiedKey)
 94     {
 95         if (map != null && !map.isEmpty() && qualifiedKey != null)
 96         {
 97             String input = String.valueOf(qualifiedKey);
 98             if (!"".equals(input))
 99             {
100                 if (input.contains("."))
101                 {
102                     int index = input.indexOf(".");
103                     String left = input.substring(0, index);
104                     String right = input.substring(index + 1, input.length());
105                     return getProperty((Map<?, ?>) map.get(left), right);
106                 }
107                 else if (map.containsKey(input))
108                 {
109                     return map.get(input);
110                 }
111                 else
112                 {
113                     return null;
114                 }
115             }
116         }
117         return null;
118     }
119 
120     /**
121      * 获取参数不为空值
122      *
123      * @param value defaultValue 要判断的value
124      * @return value 返回值
125      */
126     public static <T> T nvl(T value, T defaultValue)
127     {
128         return value != null ? value : defaultValue;
129     }
130 
131     /**
132      * 获取FTP的地址
133      */
134     public static String getFtpHost()
135     {
136         return nvl(getConfig("ftp.ftpHost"), "");
137     }
138 
139     /**
140      * 获取FTP的端口
141      */
142     public static String getFtpPort()
143     {
144         return nvl(getConfig("ftp.ftpPort"), "");
145     }
146     /**
147      * 获取连接FTP的账号
148      */
149     public static String getFtpUserName()
150     {
151         return nvl(getConfig("ftp.ftpUserName"), "");
152     }
153     /**
154      * 获取账号密码
155      */
156     public static String getFtpPassword()
157     {
158         return nvl(getConfig("ftp.ftpPassword"), "");
159     }
160     /**
161      * 获取访问FTP的路径
162      */
163     public static String getFtpRemotePath()
164     {
165         return nvl(getConfig("ftp.ftpRemotePath"), "");
166     }
167     /**
168      * 获取本地下载路径
169      */
170     public static String getFtpLocalPath()
171     {
172         return nvl(getConfig("ftp.ftpLocalPath"), "");
173     }
174 }
View Code

 

 注意,这里需要引入的yml解析器的依赖

       <!-- yml解析器 -->
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
        </dependency>

 

三、编写连接FTP工具类,用于连接FTP服务器

在项目pom.xml引入两个依赖包,一个是连接ftp需要的,另一个是作为打印日志需要的lombok

      <!--FTP-->
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.6</version>
        </dependency>
    <!--日志-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>            

 下面就是连接ftp的工具类

 1 package com.example.springboot.utils;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 import org.apache.commons.net.ftp.FTPClient;
 5 import org.apache.commons.net.ftp.FTPReply;
 6 
 7 import java.io.IOException;
 8 import java.net.SocketException;
 9 
10 /**
11  * 连接ftp服务器工具类
12  *
13  * @Author: yaodengyan
14  * @Date: 2019/11/7
15  * @Version: 1.0
16  */
17 @Slf4j
18 public class FtpUtils {
19     public static FTPClient getFTPClient() {
20         FTPClient ftpClient = new FTPClient();
21         try {
22             ftpClient = new FTPClient();
23             ftpClient.connect(YmlUtils.getFtpHost(), Integer.valueOf(YmlUtils.getFtpPort()));// 连接FTP服务器
24             ftpClient.login(YmlUtils.getFtpUserName(), YmlUtils.getFtpPassword());// 登陆FTP服务器
25             if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
26                 log.error("未连接到FTP,用户名或密码错误。{}");
27                 ftpClient.disconnect();
28             } else {
29                 log.info("FTP连接成功{}");
30             }
31         } catch (SocketException e) {
32             e.printStackTrace();
33             log.error("FTP连接失败");
34         } catch (IOException e) {
35             e.printStackTrace();
36             log.error("FTP的端口错误,请正确配置。");
37         }
38         return ftpClient;
39     }
40 }
View Code

 

四、编写下载类实现从ftp服务器下载

 1 package com.example.springboot.utils;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 import org.apache.commons.net.ftp.FTPClient;
 5 
 6 import java.io.*;
 7 import java.net.SocketException;
 8 
 9 /**
10  * ftp文件下载类
11  *
12  * @Author: yaodengyan
13  * @Date: 2019/11/7
14  * @Version: 1.0
15  */
16 @Slf4j
17 public class DowdFile {
18     public static void downloadFile(String fileName) throws IOException {
19         FTPClient ftpClient = null;
20         OutputStream os = null;
21         try {
22             ftpClient = FtpUtils.getFTPClient();
23             ftpClient.setControlEncoding("UTF-8"); // 中文支持
24             ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
25             ftpClient.enterLocalPassiveMode();
26 
27             Boolean changeDirectory = ftpClient.changeWorkingDirectory(YmlUtils.getFtpRemotePath());//切换到ftp的目标路径
28             if (!changeDirectory) {
29                 throw new RuntimeException("切换目录失败");
30             }
31             File localFile = new File(YmlUtils.getFtpLocalPath() + File.separatorChar + fileName);
32              os = new FileOutputStream(localFile);
33 
34             ftpClient.retrieveFile(fileName, os);//开始下载
35             log.info("文件下载成功");
36         } catch (FileNotFoundException e) {
37             log.error("没有找到" + YmlUtils.getFtpRemotePath() + "文件");
38             e.printStackTrace();
39         } catch (SocketException e) {
40             log.error("连接FTP失败.");
41             e.printStackTrace();
42         } catch (IOException e) {
43             e.printStackTrace();
44             log.error("文件读取错误。");
45             e.printStackTrace();
46         }finally {
47             os.close();
48             ftpClient.disconnect();
49             log.info("FTP连接断开");
50         }
51     }
52 }
View Code

 

五、编写上传文件到ftp服务器类

 1 package com.example.springboot.utils;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 import org.apache.commons.net.ftp.FTP;
 5 import org.apache.commons.net.ftp.FTPClient;
 6 
 7 import java.io.File;
 8 import java.io.FileInputStream;
 9 import java.io.FileNotFoundException;
10 import java.io.IOException;
11 
12 /**
13  * 类说明
14  *
15  * @Author: yaodengyan
16  * @Date: 2019/11/7
17  * @Version: 1.0
18  */
19 @Slf4j
20 public class UploadFile {
21     public static void uploadFile(String fileName) throws IOException {
22         FTPClient ftp = null;
23         FileInputStream input = new FileInputStream(new File(YmlUtils.getFtpLocalPath()+ File.separatorChar+fileName));
24         try {
25             ftp = FtpUtils.getFTPClient();
26             log.info("连接FTP成功!");
27             ftp.changeWorkingDirectory(YmlUtils.getFtpRemotePath());
28             ftp.setFileType(FTP.BINARY_FILE_TYPE);
29             fileName = new String(fileName.getBytes("GBK"),"iso-8859-1");
30             ftp.storeFile(fileName, input);
31             log.info("上传成功{}");
32         } catch (Exception e) {
33             e.printStackTrace();
34             log.error("文件上传失败{}");
35         }finally {
36             input.close();
37             ftp.disconnect();
38             log.info("FTP连接断开{}");
39     }
40   }
41 
42     public static void main(String[] args) throws IOException {
43         uploadFile("test.txt");
44     }
45 }
View Code

 

 

六、测试结果

获取连接

 

文件下载

在我的D盘可以看到下载的文件:

 

文件上传:

 

 ftp服务器上面:

 

 


 

七:总结

1.ftp的配置应当写在配置类,方便以后修改。

2.上传下载都是在获得ftp连接的基础上,获得连接也是最重要的一步。

 

后话:demo是学习一直知识点最好的方式!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

推荐阅读