Linux上搭建一个FTP文件服务器,很简单,网上一搜就有教程,下面是使用FTPClient实现的工具类:
package cn.rivamed.irsmartor.common;
import cn.rivamed.config.FtpProperties;
import cn.rivamed.irsmartor.enums.GlobleEnum;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.DateFormat;
import java.util.Date;
import java.util.UUID;
/**
*
*
*
* @ClassName: FTPUtils
* @Description
* @Author wuyong
* @Date 2019/8/15 16:38
* @version V1.0
*/
@SuppressWarnings("all")
@Slf4j
public class FtpUtil {
/**
* @Description 上传文件
* @param ftpProperties
* @param inputStream
* @param fileName
* @Date 2019/8/16 13:57
* @Author wuyong
* @return java.lang.String
**/
public static String upload(FtpProperties ftpProperties, FileInputStream inputStream, String originFileName) throws IOException {
FTPClient ftp = null;
String path;
String fileName;
try {
// 建立连接
ftp = connect(ftpProperties);
// 创建目录
path = mkDir(ftpProperties, ftp);
// 切换到上传目录
changeToUploadDirectory(ftp, path);
// 设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// 上传文件
fileName = upload(ftp, inputStream, originFileName);
} finally {
if (inputStream != null) {
inputStream.close();
}
if (ftp != null) {
ftp.logout();
if (ftp.isConnected()) {
ftp.disconnect();
}
}
}
return path + fileName;
}
/**
* @Description 下载
* @param ftpProperties
* @param serverUrl
* @param fileName
* @param response
* @Date 2019/8/16 15:15
* @Author wuyong
* @return void
**/
public static void download(FtpProperties ftpProperties, String serverUrl, String originFileName, HttpServletResponse response) throws IOException {
FTPClient ftpClient = null;
OutputStream outputStream = null;
try {
// 建立连接
ftpClient = connect(ftpProperties);
// 切换FTP目录
String path = serverUrl.substring(0, serverUrl.lastIndexOf("/"));
String fileName = serverUrl.substring(serverUrl.lastIndexOf("/") + 1);
boolean b = ftpClient.changeWorkingDirectory(path);
if (!b) {
return;
}
log.info("切换到下载目录成功:{}", path);
// 下载
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile file : ftpFiles) {
// 如果支持中文,只需reEncode(fileName)
if (file.isFile() && file.getName().equals(fileName)) {
outputStream = response.getOutputStream();
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName=" + new String(originFileName.getBytes("UTF-8"), "ISO-8859-1"));
ftpClient.retrieveFile(file.getName(), outputStream);
outputStream.close();
log.info("下载成功");
}
}
} finally {
if (ftpClient != null) {
// 释放资源
ftpClient.logout();
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (outputStream != null) {
outputStream.close();
}
}
}
/**
* @Description 删除
* @param pathname
* @param filename
* @Date 2019/8/16 15:31
* @Author wuyong
* @return boolean
**/
public static boolean delete(FtpProperties ftpProperties, String serverUrl) throws Exception {
FTPClient ftpClient = null;
try {
// 连接
ftpClient = connect(ftpProperties);
// 切换FTP目录
String path = serverUrl.substring(0, serverUrl.lastIndexOf("/"));
String fileName = serverUrl.substring(serverUrl.lastIndexOf("/") + 1);
boolean b = ftpClient.changeWorkingDirectory(path);
if (!b) {
return false;
}
// 删除
return ftpClient.dele(reEncode(fileName)) > 0;
} finally {
if (ftpClient != null) {
ftpClient.logout();
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static String upload(FTPClient ftp, InputStream inputStream, String originFileName) throws IOException {
// 防止文件名重复造成文件被覆盖,重新生成一个文件名保存
String fileName = UUID.randomUUID().toString().replace("-", "") + originFileName.substring(originFileName.lastIndexOf("."));
boolean b = ftp.storeFile(reEncode(fileName), inputStream);
if (!b) {
throw new BusinessException(GlobleEnum.UPLOAD_FAIL.getCode(), GlobleEnum.UPLOAD_FAIL.getMessage());
}
log.info("上传成功");
return fileName;
}
private static void changeToUploadDirectory(FTPClient ftp, String path) throws IOException {
boolean b = ftp.changeWorkingDirectory(path);
if (!b) {
throw new BusinessException(GlobleEnum.CHANGE_DIR_FAIL.getCode(), GlobleEnum.CHANGE_DIR_FAIL.getMessage() + ": " + path);
}
log.info("切换到上传目录成功");
}
private static String mkDir(FtpProperties ftpProperties, FTPClient ftp) throws IOException {
// 服务器保存根路径,如果配置的基础路径不是以/结尾,则加一个/
String path = ftpProperties.getPath();
path = StringUtils.isBlank(path) ? "/data/" : path;
path = path.startsWith("/") ? path : "/" + path;
path = path.endsWith("/") ? path : path + "/";
DateFormat dateFormat = DateFormatUtil.applyPattern("yyyy/MM/dd").get();
// 以日期作为子目录
String childPath = dateFormat.format(new Date());
for (String p : childPath.split("/")) {
path = path + p + "/";
path = reEncode(path);
// 防止中文乱码
ftp.makeDirectory(path);
if (!ftp.changeWorkingDirectory(path)) {
throw new BusinessException(GlobleEnum.MK_DIR_FAIL.getCode(), GlobleEnum.MK_DIR_FAIL.getMessage() + ": " + path);
}
log.info("创建目录: {} 成功:", path);
}
return path;
}
private static FTPClient connect(FtpProperties ftpProperties) throws IOException {
String host = ftpProperties.getHost();
int port = ftpProperties.getPort();
String username = ftpProperties.getUsername();
String password = ftpProperties.getPassword();
Assert.notEmpty(username, "ftp username is required");
Assert.notEmpty(password, "ftp password is required");
FTPClient ftp = new FTPClient();
ftp.connect(host, port);
ftp.login(username, password);
int replyCode = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
throw new BusinessException(GlobleEnum.CONNECT_FTP_FAIL.getCode(), GlobleEnum.CONNECT_FTP_FAIL.getMessage());
}
log.info("连接ftp服务器成功!");
return ftp;
}
private static String reEncode(String str) throws UnsupportedEncodingException {
return new String(str.getBytes("GBK"), "iso-8859-1");
}
}