> 文章列表 > Java读取传输FTP文件方案-源码分享

Java读取传输FTP文件方案-源码分享

Java读取传输FTP文件方案-源码分享

FTP文件服务器,通过java进行统一处理。

文章目录

  • 一.需求
  • 二.依赖
  • 三.关键源码
    • 3.0 配置信息
    • 3.1 获取客户端
    • 3.2 获取ftp文件
    • 3.3 关闭ftp服务连接
  • 三.总结

一.需求

FTP作为文件服务器,由提供服务方提供远程连接地址,连接端口,账号,密码等信息。
根据以上信息可以建立客户端连接,随后对于建立好的连接可进行文件读取,文件上传等操作

二.依赖

<!-- FTP相关操作的依赖 -->
<dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.9.0</version>
</dependency>
<!-- IO工具类的依赖 -->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version>
</dependency>
<!-- lombok依赖 -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version><scope>provided</scope>
</dependency>

三.关键源码

3.0 配置信息

ftp:config:host: ${env.ftp.config.host:10.1.1.1}port: ${env.ftp.config.port:12345}username: ${env.ftp.config.username:ftpUsername}password: ${env.ftp.config.password:ftpPwd}remote-dir-path: ${env.ftp.config.remote-dir-path:/}
/*** @author: Vainycos* @description ftp配置信息* @date: 2023/4/17 15:16*/
@Data
@Component
@ConfigurationProperties("ftp.config")
public class FtpConfig {private String host;private int port;private String username;private String password;/** 初始读取根目录,当前默认/ */private String remoteDirPath;
}

3.1 获取客户端

/**
* 获取ftp客户端
* @return
*/
public FTPClient getFtpClient(){try {FTPClient ftpClient = new FTPClient();ftpClient.connect(ftpConfig.getHost() ,ftpConfig.getPort());// 10分钟连接时间ftpClient.setConnectTimeout(600000);ftpClient.setDefaultTimeout(600000);ftpClient.login(ftpConfig.getUsername() ,ftpConfig.getPassword());// login后设置传输的模式ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// login后设置被动模式ftpClient.enterLocalPassiveMode();// login后设置编码String LOCAL_CHARSET = "GBK";// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {LOCAL_CHARSET = "UTF-8";}ftpClient.setControlEncoding(LOCAL_CHARSET);if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {log.error("未连接到FTP,用户名或密码错误!");ftpClient.disconnect();} else {log.info("FTP连接成功!");}// 切换从某个根目录下开始扫描ftpClient.changeWorkingDirectory(ftpConfig.getRemoteDirPath());return ftpClient;}catch (IOException e) {log.error("ftp建立连接异常->{}", e);}return null;
}

3.2 获取ftp文件

/**
* 获取对应目录下的第一级目录文件
* @param ftpClient client
* @throws IOException
*/
public void getFtpFirstDirectoryFiles(FTPClient ftpClient) throws IOException {log.info("ftpclient当前工作目录->{}", ftpClient.printWorkingDirectory());if (ftpClient != null) {FTPFile[] files = ftpClient.listFiles();for (FTPFile file : files) {String fileName = file.getName();if (file.isDirectory()){// 每次从根目录下查找第一级目录String firstDirectory = ftpConfig.getRemoteDirPath() + "/" + fileName;ftpClient.changeWorkingDirectory(firstDirectory);log.info("当前目录->{}, 开始扫描录音文件", firstDirectory);// 切换目录后直接遍历第一级的文件,不递归第二级目录dealFile(ftpClient);log.info("{}->目录扫描结束", firstDirectory);}}}
}/*** 处理目录下的文件* @param ftpClient* @throws IOException*/
public void dealFile(FTPClient ftpClient) throws IOException {FTPFile[] files = ftpClient.listFiles();for (FTPFile file : files) {String fileName = file.getName();if (file.isDirectory()) {log.info("{}->为目录,跳过", fileName);continue;}String rootWorkingDirectory = ftpClient.printWorkingDirectory();log.info("获取到文件->{}, 开始获取ftp文件流, ftpclient工作目录->{}", fileName, ftpClient.printWorkingDirectory());// 开始获取ftp文件流InputStream inputStream = ftpClient.retrieveFileStream(new String(fileName.getBytes("UTF-8"), FTP.DEFAULT_CONTROL_ENCODING));if (inputStream == null){log.error("文件不存在->{}", fileName);return;}byte[] data = IOUtils.toByteArray(inputStream);inputStream.close();// 关键代码,如果不执行该代码,后续的ftpClient操作将会不生效ftpClient.completePendingCommand();// 省略...获取到了inputStream 文件流进行后续处理}
}

3.3 关闭ftp服务连接

/*** 关闭FTP服务连接* @param ftpClient*/
public void disConnection(FTPClient ftpClient) {try{if(ftpClient.isConnected()){ftpClient.disconnect();}}catch(IOException e) {log.error("ftpClient.disconnect失败->{}", e);}
}

三.总结

上述源码仅供参考,具体需根据实际业务需求进行调整。主要注意点为读取中文文件名的文件以及获取ftpClient文件流之后的处理,已标注在注释中,希望能够帮助读者少踩坑。

参考资料:

  • 基于ftp协议的文件变化主动监听
  • FTPSClient解决无法获取文件问题(listFiles为空)
  • ftpClient.retrieveFileStream导致FTPClient的后面操作失败