- 引入依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
- 封装工具类,实现文件上传、文件复制等。
@Slf4j
public class FTPUtil {
private static String FTP_ADDRESS = "ip";
private static Integer FTP_PORT = 21;
private static String FTP_USERNAME = "用户名";
private static String FTP_PASSWORD = "密码";
private static String FTP_BASEPATH = "ftp服务器基础目录";
//根据当前文件生成 文件夹
private static String getTimePath() {
Date now = new Date();
DateFormat format = new SimpleDateFormat("yyyyMMdd/");
return format.format(now);
}
public static synchronized String upload(InputStream fileInputStream, String originName) throws FileNotFoundException {
String basepath = "";
if (originName.endsWith("pdf")){
basepath = FTP_BASEPATH + "pdf/";
}else {
basepath = FTP_BASEPATH + "img/";
}
StringBuilder url = new StringBuilder();
FTPClient ftp = new FTPClient();
ftp.setControlEncoding("UTF-8");
try {
// 连接FTP服务器
ftp.connect(FTP_ADDRESS, FTP_PORT);
// 登录
ftp.login(FTP_USERNAME, FTP_PASSWORD);
//开启被动模式,否则文件上传不成功,也不报错
ftp.enterLocalPassiveMode();
String timePath = getTimePath();
String saveDir = basepath + timePath;
url.append(saveDir);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
createDir(ftp, saveDir);
originName = System.currentTimeMillis() + originName;
url.append(originName);
ftp.storeFile(originName, fileInputStream);
fileInputStream.close();
ftp.logout();
} catch (IOException e) {
log.info(e.getMessage(),e);
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return url.toString();
}
// 创建文件夹,并切换到该文件夹
// 比如: hello/test
//最终会切换到test 文件夹返回
private static void createDir(FTPClient client, String path) throws IOException {
String[] dirs = path.split("/");
for (String dir : dirs) {
if (!StringUtils.hasText(dir)) {
continue;
}
if (!client.changeWorkingDirectory(dir)) {
client.makeDirectory(dir);
}
client.changeWorkingDirectory(dir);
}
}
public static void copy(String filePath, String target) throws IOException {
FTPClient ftp = new FTPClient();
ftp.setControlEncoding("UTF-8");
try {
// 连接FTP服务器
ftp.connect(FTP_ADDRESS, FTP_PORT);
// 登录
ftp.login(FTP_USERNAME, FTP_PASSWORD);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
//开启被动模式,否则文件上传不成功,也不报错
ftp.enterLocalPassiveMode();
ftp.setBufferSize(1024 * 500);
ByteArrayOutputStream fos=new ByteArrayOutputStream();
fos.flush();
ftp.retrieveFile(filePath, fos);
ByteArrayInputStream in=new ByteArrayInputStream(fos.toByteArray());
in.close();
ftp.storeFile(target, in);
fos.close();
}catch (Exception e){
log.info(e.getMessage(),e);
}finally {
if (ftp.isConnected()){
try {
ftp.disconnect();
} catch (IOException e) {
log.info(e.getMessage(),e);
}
}
}
}
}
- 上传或者复制文件时数据丢失问题
FtpClient默认使用的是ASCII形式传输的,如果只传输英文字符的文件没有问题,如果是二进制文件就会有问题,所以统一将传输编码改为UTF-8,将传输内容改为二进制内容。
// 连接FTP服务器
ftp.connect(FTP_ADDRESS, FTP_PORT);
// 登录
ftp.login(FTP_USERNAME, FTP_PASSWORD);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setControlEncoding("UTF-8");
//开启被动模式,否则文件上传不成功,也不报错
ftp.enterLocalPassiveMode();
注意设置这几个参数的顺序,要在login方法调用之后。