FTP 服务连接工具:FileZilla 安装配置
<dependency>
<groupId>commons-netgroupId>
<artifactId>commons-netartifactId>
<version>3.3version>
<scope>compilescope>
dependency>
spring:
ftp:
ip: 192.168.40.138
port: 14147
username: root
password: 123456
path: D:/filezillawork
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.net.SocketException;
/**
* hbcx工区FTP服务器配置
*/
@Data
@Slf4j
@Configuration
public class FtpConfig {
/**
* FTP IP地址
*/
@Value("${spring.ftp.ip}")
private String ip;
/**
* FTP端口号
*/
@Value("${spring.ftp.port}")
private Integer port;
/**
* FTP登录账号
*/
@Value("${spring.ftp.username}")
private String username;
/**
* FTP登录密码
*/
@Value("${spring.ftp.password}")
private String password;
/**
* FTP工作路径
*/
@Value("${spring.ftp.path}")
private String path;
private FTPClient ftpClient;
/**
* 连接 FTP 服务
*/
public FTPClient connect() {
ftpClient = new FTPClient();
try {
// 设置编码
ftpClient.setControlEncoding("UTF-8");
// 设置连接超时时间(单位:毫秒)
ftpClient.setConnectTimeout(10 * 1000);
// 连接
ftpClient.connect(ip, port);
// 登录
ftpClient.login(username, password);
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
log.error("未连接到FTP,用户名或密码错误");
// 拒绝连接
ftpClient.disconnect();
} else {
log.info("连接到FTP成功");
// 设置二进制方式传输文件
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 设置被动工作模式
ftpClient.enterLocalPassiveMode();
}
return ftpClient;
} catch (SocketException e) {
e.printStackTrace();
log.error("FTP的IP地址错误");
} catch (IOException e) {
e.printStackTrace();
log.error("FTP的端口错误");
}
return ftpClient;
}
/**
* 断开 FTP 服务
*/
public void closeConnect() {
log.warn("关闭ftp服务器");
try {
if (ftpClient != null) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
import com.boyia.ftpdemov2.config.FtpConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.stereotype.Component;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 2023/2/5 15:04
*
* @author HZ
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class FtpUtil {
private final FtpConfig ftpConfig;
public static final String DIR_SPLIT = "/";
/**
* 获取 FTPClient
* @return FTPClient
*/
private FTPClient getFTPClient() {
FTPClient ftpClient = ftpConfig.connect();
if (ftpClient == null || !FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
throw new RuntimeException("ftp客户端异常");
}
return ftpClient;
}
/**
* 获取FTP某一特定目录下的所有文件名称
*
* @param ftpDirPath FTP上的目标文件路径
*/
public List<String> getFileNameList(String ftpDirPath) {
FTPClient ftpClient = getFTPClient();
try {
// 通过提供的文件路径获取 FTPFile 文件列表
// FTPFile[] ftpFiles = ftpClient.listFiles(ftpDirPath, FTPFile::isFile); // 只获取文件
// FTPFile[] ftpFiles = ftpClient.listFiles(ftpDirPath, FTPFile::isDirectory); // 只获取目录
FTPFile[] ftpFiles = ftpClient.listFiles(ftpDirPath);
if (ftpFiles != null && ftpFiles.length > 0) {
return Arrays.stream(ftpFiles).map(FTPFile::getName).collect(Collectors.toList());
}
log.error(String.format("路径有误,或目录【%s】为空", ftpDirPath));
} catch (IOException e) {
log.error("文件获取异常:", e);
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 上传文件
*
* @param uploadPath 上传路径
* @param fileName 文件名
* @param input 文件输入流
* @return 上传结果
*/
public boolean upload(String uploadPath, String fileName, InputStream input) {
FTPClient ftpClient = getFTPClient();
try {
// 切换到工作目录
if (!ftpClient.changeWorkingDirectory(uploadPath)) {
ftpClient.makeDirectory(uploadPath);
ftpClient.changeWorkingDirectory(uploadPath);
}
// 文件写入
boolean storeFile = ftpClient.storeFile(fileName, input);
if (storeFile) {
log.info("文件:{}上传成功", fileName);
} else {
throw new RuntimeException("ftp文件写入异常");
}
ftpClient.logout();
return true;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
if (ftpClient.isConnected()) {
ftpClient.disconnect();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return false;
}
/**
* 下载文件 *
*
* @param ftpPath FTP服务器文件目录 *
* @param ftpFileName 文件名称 *
* @param localPath 下载后的文件路径 *
* @return
*/
public boolean download(String ftpPath, String ftpFileName, String localPath) {
FTPClient ftpClient = getFTPClient();
OutputStream outputStream = null;
try {
FTPFile[] ftpFiles = ftpClient.listFiles(ftpPath, file -> file.isFile() && file.getName().equals(ftpFileName));
if (ftpFiles != null && ftpFiles.length > 0) {
FTPFile ftpFile = ftpFiles[0];
File localFile = new File(localPath + DIR_SPLIT + ftpFile.getName());
// 判断本地路径目录是否存在,不存在则创建
if (!localFile.getParentFile().exists()) {
localFile.getParentFile().mkdirs();
}
outputStream = Files.newOutputStream(localFile.toPath());
ftpClient.retrieveFile(ftpFile.getName(), outputStream);
log.info("fileName:{},size:{}", ftpFile.getName(), ftpFile.getSize());
log.info("下载文件成功...");
return true;
} else {
log.info("文件不存在,filePathname:{},", ftpPath + DIR_SPLIT + ftpFileName);
}
} catch (Exception e) {
log.error("下载文件失败...");
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
/**
* 从FTP服务器删除文件或目录
* 存在文件的目录无法删除
*
* @param ftpPath 服务器文件存储路径
* @param fileName 服务器文件存储名称
* @return 删除结果
*/
public boolean delete(String ftpPath, String fileName) {
FTPClient ftpClient = getFTPClient();
try {
// 在 ftp 目录下获取文件名与 fileName 匹配的文件信息
FTPFile[] ftpFiles = ftpClient.listFiles(ftpPath, file -> file.getName().equals(fileName));
// 删除文件
if (ftpFiles != null && ftpFiles.length > 0) {
boolean del;
String deleteFilePath = ftpPath + DIR_SPLIT + fileName;
FTPFile ftpFile = ftpFiles[0];
if (ftpFile.isDirectory()) {
del = ftpClient.removeDirectory(deleteFilePath);
} else {
del = ftpClient.deleteFile(deleteFilePath);
}
log.info(del ? "文件:{}删除成功" : "文件:{}删除失败", fileName);
return del;
} else {
log.warn("文件:{}未找到", fileName);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
}
注意:此处的根目录 “./” 等同于 FTP 的共享文件夹目录
@RestController
@RequestMapping("/ftp")
@RequiredArgsConstructor
public class FtpController {
private final FtpUtil ftpUtil;
private static final String ROOT_DIR = "./";
@GetMapping("/getFileNameList")
public List<String> getFileNameList() {
return ftpUtil.getFileNameList(ROOT_DIR);
}
@PostMapping("/upload")
public boolean uploadToFtpServer(MultipartFile file) throws IOException {
// 读取文件信息
String fileName = file.getOriginalFilename();
InputStream fileInputStream = file.getInputStream();
// 上传文件到 Ftp 服务
return ftpUtil.upload(ROOT_DIR, fileName, fileInputStream);
}
@GetMapping("/download")
public boolean download(){
String localPath = "C:/Users/A/Desktop/243.jpg", ftpFileName = "330.png";
return ftpUtil.download(ROOT_DIR, ftpFileName, localPath);
}
@GetMapping("/delete")
public boolean delete(String fileName){
return ftpUtil.delete(ROOT_DIR, fileName);
}
}