背景
在项目中经常需要用到文件上传,使用FTP服务可以将文件存储于项目运行处分离开
于是我打算使用FTP服务 ,并且选择了vsftpd
安装教程
1.使用命令在线安装vsftpd
代码语言:shell复制yum -y install vsftpd
2.关闭匿名访问
代码语言:txt复制vim /etc/vsftpd/vsftpd.conf
anonymous_enable = NO
3.启动服务
代码语言:txt复制systemctl start vsftpd.service
4.查看ftp服务状态
代码语言:txt复制systemctl status vsftpd.service
active(running)表示运行成功
5.开放防火墙访问端口
代码语言:txt复制firewall-cmd --zone=public --add-port=21/tcp --permanent
firewall-cmd --zone=public --add-port=1025-65535/tcp --permanent
systemctl restart firewalld
查看防火墙状态(我在本地虚拟机中是直接禁用防火墙了的 仅供参考)
代码语言:txt复制# 关闭
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld
# 查看防火墙状态
systemctl status firewalld
6.添加用户和密码
代码语言:txt复制adduser user-file
passwd user-file
7.在ftp服务中上传的文件都存在了虚拟机的/home/user-file中
存在了home目录下的用户名目录
集成Springboot实现文件上传
代码语言:java复制@Slf4j
@Component
public class FtpHelper {
//FTPClient的配置
@Autowired
private FtpClientConfig ftpClientConfig;
//静态的用于在工具类接收自动装配的config
private static FtpClientConfig ftpConfig;
//静态的FTPClient
private static FTPClient ftp;
//仓库文件名
private static String StockRoom = "/store";
//在spring容器初始化的时候执行
@PostConstruct
public void setconfig() {
ftpConfig=ftpClientConfig;
}
/**
* 初始化FTPClient
* @return
*/
public static boolean initFtpClient() {
ftp = new FTPClient();
try {
ftp.connect(ftpConfig.host, ftpConfig.port);
int replyCode = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(replyCode)){
ftp.disconnect();
log.warn("FTPServer refused connection,replyCode:{}", replyCode);
return false;
}
if(!ftp.login(ftpConfig.username,ftpConfig.password)){
log.warn("ftpClient login failed... username is {}; password: {}", ftpConfig.username, ftpConfig.password);
return false;
}
ftp.setBufferSize(10240);
ftp.setDataTimeout(600000*60);
ftp.setConnectTimeout(600000*60);
ftp.setFileType(FTP.BINARY_FILE_TYPE);//二进制
ftp.enterLocalPassiveMode();//被动模式
} catch (IOException e) {
log.error("create ftp connection failed...", e);
}
return true;
}
/**
* 上传文件
* @param multipartFile
* @param newName
* @return
*/
public static boolean uploadFile(MultipartFile multipartFile,String newName){
InputStream inputStream =null;
if(!initFtpClient()){
return false;
}
try {
inputStream= multipartFile.getInputStream();
log.info("start upload... {}", multipartFile.getOriginalFilename());
String overPath = ftpConfig.basepath StockRoom "/" LocalDate.now();
boolean dirSuccess = ftp.changeWorkingDirectory(overPath);
if(!dirSuccess){
ftp.makeDirectory(ftpConfig.basepath StockRoom);
ftp.makeDirectory(overPath);2023-01-07
ftp.changeWorkingDirectory(overPath);
}
boolean storeFileFlag = ftp.storeFile(new String(newName.getBytes("GBK"), "iso-8859-1"), inputStream);
if(storeFileFlag){
log.info("upload file success! {}", multipartFile.getOriginalFilename());
return true;
}
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
log.warn("upload file failure! {}", multipartFile.getOriginalFilename());
return false;
}
/**
* 文件下载
* @param outputStream
* @param path
* @param storename
* @param displayName
* @return
*/
public static boolean downloadFile(OutputStream outputStream,String path,String storename,String displayName) {
if(!initFtpClient()){
return false;
}
String overPath = ftpConfig.basepath StockRoom path "/" storename;
log.info("start download... {}", displayName);
try {
boolean retrieveFileFlag = ftp.retrieveFile(new String(overPath.getBytes("GBK"), "iso-8859-1"), outputStream);
if(retrieveFileFlag){
log.warn("download file success! {}", displayName);
return true;
}
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(outputStream);
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
log.warn("download file failure! {}", displayName);
return false;
}
}
想在Nginx映射这个目录实现可访问下载
在Nginx配置中设置
代码语言:javascript复制user user-file
代码语言:javascript复制 server {
listen 6000;
location / {
autoindex on;
root /home/user-file;
}
}