最近项目上需要使用ftp服务器和第三方进行资源交互,于是写了个小demo记录下~
基础知识
FTP服务器
多级目录下创建文件
一直以为ftp服务器多级目录创建和java中目录创建一样,然而并不是滴~ 可参考文档:关于ftp上传changeWorkingDirectory()方法的路径切换问题
将文件hello.json
上传至/home/upload/
目录下步骤:
- 先使用
FTPClient.changeWorkingDirectory("home")
,判断home目录是否存在?若不存在则2 - 使用
FTPClient.makeDirectory("home")
创建目录,同时使用FTPClient.changeWorkingDirectory("home")
将ftp session指向home目录 - 使用
FTPClient.changeWorkingDirectory("upload")
判断upload目录是否存在?若不存在则4 - 使用
FTPClient.makeDirectory("upload")
创建目录,同时使用FTPClient.changeWorkingDirectory("upload")
将ftp session指向upload目录 - 使用
FTPClient.storeFile(fileName, is);
上传文件流is
实践出真知
引入依赖和加入配置
- pom.xml 中添加依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
- 在application.yml中添加ftp服务器配置(多环境则需要在application-dev/test/prod.yml中分别配置)
ftp:
hostname: 172.16.1.1
port: 21
username: lizzy
password: lizzy
root-path: /upload/
定义配置bean
package com.lizzy.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;
@ConfigurationProperties(prefix = "ftp")
@Data
@Component
public class FtpConfig {
private String hostname;
private Integer port;
private String username;
private String password;
private String rootPath;
}
定义FTP工具类
上传
package com.lizzy.common.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.util.StringUtils;
import com.ankon.common.config.FtpConfig;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
@UtilityClass
@Slf4j
public class FTPUtil {
/**
* 上传文件至FTP服务器
* @param config ftp服务器配置
* @param path 文件子路径
* @param fileName 文件名
* @param is 文件流
*/
public static void upload(FtpConfig config, String path, String fileName, InputStream is) {
FTPClient client = new FTPClient();
client.enterLocalPassiveMode();
try {
// 连接服务器
client.connect(config.getHostname(), config.getPort());
// 登录
client.login(config.getUsername(), config.getPassword());
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
// 连接失败
client.disconnect();
log.info("FTP服务器配置链接失败!请检查配置:{}", config.toString());
return ;
}
// 切换到上传目录
final String filePath = config.getRootPath() + path;
if (!client.changeWorkingDirectory(filePath)) {
// 目录不存在则创建
String[] dirs = filePath.split("/");
for (String dir : dirs) {
if (StringUtils.isEmpty(dir)) {
continue ;
}
if (!client.changeWorkingDirectory(dir)) {
client.makeDirectory(dir);
client.changeWorkingDirectory(dir);
}
}
}
//设置上传文件的类型为二进制类型
client.setFileType(FTP.BINARY_FILE_TYPE);
client.storeFile(fileName, is);
log.debug("文件{}成功上传至FTP服务器!", filePath + "/" + fileName);
client.logout();
} catch (IOException e) {
log.info("FTP服务器配置链接失败!错误:{}", e.getMessage());
e.printStackTrace();
} finally {
try {
is.close();
if (client.isConnected()) {
client.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
下载
package com.lizzy.common.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.util.StringUtils;
import com.ankon.common.config.FtpConfig;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
@UtilityClass
@Slf4j
public class FTPUtil {
/**
* 从FTP服务器下载文件流
* @param config FTP服务器配置
* @param path 相对目录(不包含根目录)
* @param fileName 文件名
* @return
*/
public static InputStream download(FtpConfig config, String path, String fileName) {
FTPClient client = new FTPClient();
client.enterLocalPassiveMode();
try {
// 连接服务器
client.connect(config.getHostname(), config.getPort());
// 登录
client.login(config.getUsername(), config.getPassword());
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
// 连接失败
client.disconnect();
log.info("FTP服务器配置链接失败!请检查配置:{}", config.toString());
return null;
}
// 切换到下载目录
final String filePath = config.getRootPath() + path;
client.changeWorkingDirectory(filePath);
//设置上传文件的类型为二进制类型
client.setFileType(FTP.BINARY_FILE_TYPE);
InputStream is = client.retrieveFileStream(fileName);
log.debug("从FTP服务器下载文件({})成功!", fileName);
return is;
} catch (IOException e) {
log.info("FTP服务器配置链接失败!错误:{}", e.getMessage());
e.printStackTrace();
} finally {
try {
client.logout();
if (client.isConnected()) {
client.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
遇到的问题
文件覆盖
后记
demo写的很匆忙,后续遇到问题了再更新~