目前项目内部需求是将FTP文件服务器上的各类office和pdf文件读取出来返回给前端进行预览展示
1.配置ftp访问信息,并读取配置
/**
* ftp配置信息
*/
@Component
@ConfigurationProperties(prefix = "ftp.server")
@Data
public class FtpPropertiesConfig {
/**
* IP地址
*/
private String host;
/**
* 端口
*/
private String port;
/**
* 登陆用户名
*/
private String userName;
/**
* 密码
*/
private String password;
}
2.ftp工具类实现
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
/**
* FTP文件操作工具类
*/
@Component
public class FtpUtils {
private static final Logger log = LoggerFactory.getLogger(FtpUtils.class);
public static final String FTP_FILE_PATH = "/home/ftptest/";
private static FtpPropertiesConfig ftpPropertiesConfig;
//注入ftp配置
@Autowired
private FtpPropertiesConfig ftpConfig;
@PostConstruct
public void init(){
FtpUtils.ftpPropertiesConfig = ftpConfig;
}
/**
* 登陆FTP服务器
*
* @param host FTPServer IP地址
* @param port FTPServer 端口
* @param userName FTPServer 登陆用户名
* @param password FTPServer 登陆密码
* @return FTPClient
* @throws IOException
*/
public static FTPClient login(String host, String port, String userName, String password) throws IOException{
FTPClient ftpClient = new FTPClient();
// 防止中文目录乱码
ftpClient.setAutodetectUTF8(true);
ftpClient.setConnectTimeout(60000);
// 连接FTP服务器
ftpClient.connect(host, Integer.valueOf(port));
if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
// 登陆FTP服务器
if (ftpClient.login(userName, password)) {
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
"OPTS UTF8", "ON"))) {
ftpClient.setControlEncoding("UTF-8");
}else {
ftpClient.setControlEncoding("GBK");
}
// 设置传输的模式,以二进制流的方式读取
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
log.info("FTP服务连接成功!");
}else {
log.error("FTP服务用户名或密码错误!");
disConnection(ftpClient);
}
}else {
log.error("连接到FTP服务失败!");
disConnection(ftpClient);
}
return ftpClient;
}
/**
* 关闭FTP服务链接
* @throws IOException
*/
private static void disConnection(FTPClient ftpClient) throws IOException {
if(null != ftpClient && ftpClient.isConnected()){
ftpClient.disconnect();
}
}
/**
* 获取文件夹下的所有文件信息
* @param path 文件路径
*/
public static FTPFile[] getFTPDirectoryFiles(String path) throws IOException {
FTPFile[] files = null;
FTPClient ftpClient = null;
try {
ftpClient = login(ftpPropertiesConfig.getHost(), ftpPropertiesConfig.getPort(),
ftpPropertiesConfig.getUserName(), ftpPropertiesConfig.getPassword());
// 判断是否存在该目录
if (!ftpClient.changeWorkingDirectory(path)) {
log.error("该目录不存在,filePath="+path);
}
//调用FTPClient.enterLocalPassiveMode();这个方法的意思就是每次数据连接之前,
// ftpclient告诉ftp server开通一个端口来传输数据
ftpClient.enterLocalPassiveMode();
files = ftpClient.listFiles();
}catch (Exception e){
//关闭连接
disConnection(ftpClient);
log.error("FTP读取数据异常!", e);
}finally {
disConnection(ftpClient);
}
return files;
}
public static InputStream getFTPFileStream(String filePath,String fileName) throws IOException {
FTPClient ftpClient = null;
try {
ftpClient = login(ftpPropertiesConfig.getHost(), ftpPropertiesConfig.getPort(),
ftpPropertiesConfig.getUserName(), ftpPropertiesConfig.getPassword());
// 判断是否存在该目录
if (!ftpClient.changeWorkingDirectory(filePath)) {
log.error("该目录不存在,filePath="+filePath);
}
// 设置被动模式,开通一个端口来传输数据
ftpClient.enterLocalPassiveMode();
InputStream inputStream = ftpClient.retrieveFileStream(fileName);
return inputStream;
}catch (Exception e){
//关闭连接
disConnection(ftpClient);
log.error("FTP读取文件流异常!", e);
}finally {
disConnection(ftpClient);
}
return null;
}
}
/**
* 递归遍历出目录下面所有文件
* @param pathName
* @throws IOException
*/
private void listFilesByKey(String pathName) throws IOException {
if(pathName.startsWith("/")&&pathName.endsWith("/")){
FTPFile[] files = FtpUtils.getFTPDirectoryFiles(pathName);
if (null == files){
return;
}
for (int i = 0; i < files.length; i++) {
if(files[i].isFile()){
// 如果是文件则进行处理
String fileName = files[i].getName();
// do something
}else if (files[i].isDirectory()){
if (!".".equals(files[i].getName()) && !"..".equals(files[i].getName())) {
log.info("listFilesByKey:directoryName="+files[i].getName());
// 递归调用获取子目录下的文件
listFilesByKey(pathName + files[i].getName() + "/");
}
}
}
}
}
/**
* 删除本地目录和文件
* @param filePath
* @return
*/
private boolean deleteDirectory(String filePath) {
File dirFile = new File(filePath);
if (dirFile.isDirectory()) {
File[] children = dirFile.listFiles();
log.info("deleteDirectory: files count = "+children.length);
//递归删除目录中的子目录下
for (int i=0; i< children.length; i++) {
if (children[i].isFile()) {
children[i].delete();
log.info("deleteDirectory: remove fileName = "+ children[i].getAbsolutePath());
}else {
deleteDirectory(children[i].getAbsolutePath());
}
}
}
// 删除为空目录
log.info("deleteDirectory: remove directory = "+ dirFile.getAbsolutePath());
return dirFile.delete();
}
以上就是涉及ftp文件的读取的操作方法,项目使用场景中暂无上传和更新的操作,如有纰漏欢迎吐槽。