依赖的包
      <dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.1</version></dependency>
方法示例
package com.xsh.util;import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** FTP下载工具* @author shuangxie* @date 2019/5/24*/
@Component
public class FTPUtil {/*** 日志对象**/private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class);/*** 该目录不存在*/public static final String DIR_NOT_EXIST = "该目录不存在";/*** "该目录下没有文件*/public static final String DIR_CONTAINS_NO_FILE = "该目录下没有文件";/*** FTP地址**/@Value("${ftp.host}")private String ftpAddress;/*** FTP端口**/@Value("${ftp.port}")private int ftpPort = 521;/*** FTP用户名**/@Value("${ftp.username}")private String ftpUsername;/*** FTP密码**/@Value("${ftp.password}")private String ftpPassword;/*** FTP基础目录**/@Value("${ftp.basepath}")private String basePath;/*** 本地字符编码**/private static String localCharset = "GBK";/*** FTP协议里面,规定文件名编码为iso-8859-1**/private static String serverCharset = "ISO-8859-1";/*** UTF-8字符编码**/private static final String CHARSET_UTF8 = "UTF-8";/*** OPTS UTF8字符串常量**/private static final String OPTS_UTF8 = "OPTS UTF8";/*** 设置缓冲区大小4M**/private static final int BUFFER_SIZE = 1024 * 1024 * 4;/*** FTPClient对象**/private static FTPClient ftpClient = null;/*** 下载该目录下所有文件到本地** @param ftpPath  FTP服务器上的相对路径,例如:test/123* @param savePath 保存文件到本地的路径,例如:D:/test* @return 成功返回true,否则返回false*/public boolean downloadFiles(String ftpPath, String savePath) {// 登录login(ftpAddress, ftpPort, ftpUsername, ftpPassword);if (ftpClient != null) {try {String path = changeEncoding(basePath + ftpPath);// 判断是否存在该目录if (!ftpClient.changeWorkingDirectory(path)) {logger.error(basePath + ftpPath + DIR_NOT_EXIST);return Boolean.FALSE;}ftpClient.enterLocalPassiveMode();  // 设置被动模式,开通一个端口来传输数据String[] fs = ftpClient.listNames();// 判断该目录下是否有文件if (fs == null || fs.length == 0) {logger.error(basePath + ftpPath + DIR_CONTAINS_NO_FILE);return Boolean.FALSE;}for (String ff : fs) {String ftpName = new String(ff.getBytes(serverCharset), localCharset);File file = new File(savePath + '/' + ftpName);try (OutputStream os = new FileOutputStream(file)) {ftpClient.retrieveFile(ff, os);} catch (Exception e) {logger.error(e.getMessage(), e);}}} catch (IOException e) {logger.error("下载文件失败", e);} finally {closeConnect();}}return Boolean.TRUE;}/*** 连接FTP服务器** @param address  地址,如:127.0.0.1* @param port     端口,如:21* @param username 用户名,如:root* @param password 密码,如:root*/private void login(String address, int port, String username, String password) {ftpClient = new FTPClient();try {ftpClient.connect(address, port);ftpClient.login(username, password);ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//限制缓冲区大小ftpClient.setBufferSize(BUFFER_SIZE);int reply = ftpClient.getReplyCode();if (!FTPReply.isPositiveCompletion(reply)) {closeConnect();logger.error("FTP服务器连接失败");}} catch (Exception e) {logger.error("FTP登录失败", e);}}/*** FTP服务器路径编码转换** @param ftpPath FTP服务器路径* @return String*/private static String changeEncoding(String ftpPath) {String directory = null;try {if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(OPTS_UTF8, "ON"))) {localCharset = CHARSET_UTF8;}directory = new String(ftpPath.getBytes(localCharset), serverCharset);} catch (Exception e) {logger.error("路径编码转换失败", e);}return directory;}/*** 关闭FTP连接*/private void closeConnect() {if (ftpClient != null && ftpClient.isConnected()) {try {ftpClient.logout();ftpClient.disconnect();} catch (IOException e) {logger.error("关闭FTP连接失败", e);}}}/*** 检查指定目录下是否含有指定文件** @param ftpPath  FTP服务器文件相对路径,例如:test/123* @param fileName 要下载的文件名,例如:test.txt* @return 成功返回true,否则返回false*/public boolean checkFileInFtp(String ftpPath, String fileName) {// 登录login(ftpAddress, ftpPort, ftpUsername, ftpPassword);if (ftpClient != null) {try {String path = changeEncoding(basePath + ftpPath);// 判断是否存在该目录if (!ftpClient.changeWorkingDirectory(path)) {logger.error(basePath + ftpPath + DIR_NOT_EXIST);return Boolean.FALSE;}ftpClient.enterLocalPassiveMode();  // 设置被动模式,开通一个端口来传输数据String[] fs = ftpClient.listNames();// 判断该目录下是否有文件if (fs == null || fs.length == 0) {logger.error(basePath + ftpPath + DIR_CONTAINS_NO_FILE);return Boolean.FALSE;}for (String ff : fs) {String ftpName = new String(ff.getBytes(serverCharset), localCharset);if (ftpName.equals(fileName)) {return Boolean.TRUE;}}} catch (IOException e) {logger.error("请求出错", e);} finally {closeConnect();}}return Boolean.TRUE;}/*** 下载该目录下所有文件到本地 根据实际需要修改执行逻辑** @param ftpPath  FTP服务器上的相对路径,例如:test/123* @param savePath 保存文件到本地的路径,例如:D:/test* @return 成功返回true,否则返回false*/public Map<String, Object> downLoadTableFile(String ftpPath, String savePath) {// 登录login(ftpAddress, ftpPort, ftpUsername, ftpPassword);Map<String, Object> resultMap = new HashMap<>();if (ftpClient != null) {try {String path = changeEncoding(basePath + "/" + ftpPath);// 判断是否存在该目录if (!ftpClient.changeWorkingDirectory(path)) {logger.error(basePath + "/" + ftpPath + DIR_NOT_EXIST);resultMap.put("result", false);return resultMap;}ftpClient.enterLocalPassiveMode();  // 设置被动模式,开通一个端口来传输数据String[] fs = ftpClient.listNames();// 判断该目录下是否有文件if (fs == null || fs.length == 0) {logger.error(basePath + "/" + ftpPath + DIR_CONTAINS_NO_FILE);resultMap.put("result", false);return resultMap;}List<String> tableFileNameList = new ArrayList<>();//根据表名创建文件夹String tableDirName = savePath + "/" + ftpPath;File tableDirs=new File(tableDirName);if(!tableDirs.exists()){tableDirs.mkdirs();}for (String ff : fs) {String ftpName = new String(ff.getBytes(serverCharset), localCharset);File file = new File(tableDirName + "/" + ftpName);//存储文件名导入时使用tableFileNameList.add(tableDirName + "/" + ftpName);try (OutputStream os = new FileOutputStream(file)) {ftpClient.retrieveFile(ff, os);} catch (Exception e) {logger.error(e.getMessage(), e);}}resultMap.put("fileNameList", tableFileNameList);resultMap.put("result", true);return resultMap;} catch (IOException e) {logger.error("下载文件失败", e);} finally {closeConnect();}}resultMap.put("result", false);return resultMap;}
}
单元测试
    @Autowiredprivate FTPUtil ftpUtil;/*** 本地存储路径*/@Value("${ftp.local.save.basepath}")private String localSavePath;@Testpublic void ftpDownloadTest() {Map<String, Object> result = ftpUtil.downLoadTableFile("dw_account_district", localSavePath);TestCase.assertEquals(true, result.get("result"));}
需要注意的点
  1. 需要设置缓冲区大小,防止下载过慢或者过快
  2. 需要确认ftp服务器的访问模式,被动模式还是主动模式
  3. 需要注意编码格式

源码下载:https://github.com/xieshuang/util

Java FTP下载文件相关推荐

  1. Java FTP下载文件以及编码问题小结

    问题 之前在开发过程中,遇到了一点问题,我要访问一个FTP服务器去下载文件详细情况如下: 1. 需要传入一个可能为中文的文件名: 2. 通过文件名去FTP上寻找该文件: 3. FTP服务器的命名编码为 ...

  2. java ftp下载文件源码_java实现ftp文件下载的源代码

    这几天做的一个项目中用到了ftp文件传输,用java实现了ftp文件的下载. 一.win7下搭建ftp服务器 详见:http://jingyan.baidu.com/article/4b52d7026 ...

  3. java ftp下载文件 慢_java实现ftp文件上传下载,解决慢,中文乱码,多个文件下载等问题...

    标签: //文件上传 public static boolean uploadToFTP(String url,int port,String username,String password,Str ...

  4. Java实现FTP下载文件到客户端(浏览器)

    目录 一.简介 二.maven依赖 三.配置类 四.工具类 4.1.服务器文件名中文处理 4.2.下载文件名中文处理 五.接口验证 一.简介   我在之前的文章(Java实现文件上传和下载)里讲过非F ...

  5. 【踩坑】Linux java中ftp下载文件,解压文件损坏,以及图片下载打开只显示下载路径的问题

    [踩坑]Linux java中ftp下载文件,解压文件损坏,以及图片下载打开只显示下载路径的问题 一. 问题重现 二. 问题解决思路 1. 确认是不是上传就导致数据出错了 2. 是不是平台问题 三. ...

  6. Java 实现上传文件到FTP和从FTP下载文件

    在eclipse 中创建项目,并将commons-net-3.6.jar包复制到项目中 commons-net-3.6.jar:链接:https://pan.baidu.com/s/1iz0862TX ...

  7. Java ftp实现文件的上传和下载ftp,sftp sun.net.ftp.FtpProtocolException:Welcome message: SSH-2.0-OpenSSH_5.1

    Java ftp实现文件的上传和下载 ftp,sftp 运行后发现很长时间没有反应,很久以后抛出如下异常:sun.net.ftp.FtpProtocolException:Welcome messag ...

  8. C#FTP下载文件出现远程服务器返回错误: (500) 语法错误,无法识别命令

    如果下载多个文件的时候,有时候莫名其妙的出现500服务器错误,很有可能是没有设置KeepAlive 属性导致的. 出现应用程序未处理的异常:2015/1/6 11:40:56 异常类型:WebExce ...

  9. 使用FTP下载文件connect.retrieveFileStream(filename) 获取不到InputStream流,返回null的问题

    使用同事的代码做FTP下载文件,InputStream in = connect.retrieveFileStream(fileName);执行这句时InputStream总是获取为空 后来把代码改成 ...

  10. java线程下载文件_Java多线程下载文件实例详解

    本文实例为大家分享了Java多线程下载文件的具体代码,供大家参考,具体内容如下 import java.io.File; import java.io.InputStream; import java ...

最新文章

  1. Linux学习笔记---烧写bin文件分析
  2. 很实用的一个ext表格,具有很好的分页功能。
  3. jmeter-01 JMeter HTTP测试的各元件功能演示示例
  4. 【读书笔记】终极算法
  5. 类对象实现红蓝方互殴
  6. SSL证书的概念、作用及分类、价格介绍
  7. icloud上传错误_如何修复HomeKit“地址未注册到iCloud”错误
  8. python打分系统_做一个Python颜值打分系统,比比看杨幂和杨超越到底谁更美?
  9. Python计算化学式相对分子质量(含完整代码)
  10. python用cartopy包画地图_python绘制地图的利器Cartopy使用说明
  11. android studio导入arr文件
  12. HTML 中几种常见长度单位介绍
  13. 在INTEL KABYALAKE平台上运行COREBOOT 记录
  14. JDK 18 / Java 18 正式发布:九项 JDK 增强
  15. PVM58N-YY1AGR0BN-1213光电采样编码器
  16. three.js加载sea3D模型webgl_loader_sea3d
  17. 屁股决定脑袋,人性在管理中的体现
  18. android 语言包 external,为Android添加多国语言包.pdf
  19. 优地、云迹、擎朗、普渡科技的服务机器人场景战争
  20. 年年100%增长,深信服超融合企业云做对了什么?

热门文章

  1. Hack the box: Bastion
  2. ktv无线服务器,KTV无线网络覆盖方案-无死角WIFI信号全覆盖方法
  3. 跟随阿里云贾扬清,走近AI开发者的奇幻漂流
  4. 函数发生器与计算机电路,第29讲 信号发生器与变换电路
  5. Unity 智能语音助手
  6. 2021年高处安装、维护、拆除考试及高处安装、维护、拆除考试技巧
  7. histogram函数 python_Python numpy.histogram函数方法的使用
  8. 梳理审批流程的程序编码流程
  9. django里template中的书名号
  10. 2020 年 Python 知识清单(网络爬虫)