> 📢博客主页:折戏花
>
> 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
>
> 📢本文由折戏花编写,首发于CSDN🙉
1、背景
这里我们通过apache提供的API进行实现FTP文件下载解压,使用commons-net版本3.9.0
2、代码实现
2.1、maven依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.9.0-SNAPSHOT</version>
</dependency>
2.2、初始化ftp,连接ftp
public static boolean initFtpClient(){
boolean isSuccess = false;
int reply;
ftpClient = new FTPClient();
try {
//连接Ftp服务器
ftpClient.connect("127.0.0.1", "21");
//登陆Ftp服务器
ftpClient.login("username", "password");
//设置编码类型
ftpClient.setControlEncoding(UTF8);
//获取返回码,用于判断是否连接成功
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new BusinessException("服务器连接失败");
} else {
//设置被动模式
ftpClient.enterLocalPassiveMode();
//设置字符模式,解决中文乱码问题
ftpClient.setControlEncoding(GBK);
isSuccess = true;
}
} catch (Exception e) {
log.error(e.getMessage());
}
return isSuccess;
}
注意:FTP协议有两种工作方式:PORT方式和PASV方式,中文意思为主动式和被动式(如果是IPv6,则分别是EPRT和EPSV)。主动被动都是相对于服务器来说的
所以这里我们是客户端进行连接到服务端,我们需要设置成被动模式,被动模式需要在建立FTP连接后设置
2.3、下载文件
public static boolean downFile(String path,String localPath) throws IOException {
boolean isSuccess = false;
ftpClient.changeWorkingDirectory(path);
File file = new File(localPath);
try(FileOutputStream outputStream = new FileOutputStream(file)) {
isSuccess = ftpClient.retrieveFile(file.getName(),outputStream);
}catch (Exception e){
e.printStackTrace();
}
return isSuccess;
}
2.4、解压文件
这里通过gzip解压方式进行解压
public static void unGzipFile(String fileName,String localPath) {
try(
//建立gzip解压工作流
GZIPInputStream gzip = new GZIPInputStream(ftpClient.retrieveFileStream(fileName));
FileOutputStream out = new FileOutputStream(localPath);
) {
int num;
byte[] buf=new byte[1024];
while ((num = gzip.read(buf,0,buf.length)) != -1)
{
out.write(buf,0,num);
}
} catch (Exception ex){
log.error(ex.toString());
}
}
2.5、关闭连接
public static void closeFtpClient() {
try {
//退出登陆
ftpClient.logout();
//检测是否连接Ftp服务器
if (ftpClient.isConnected()) {
//关闭连接
ftpClient.disconnect();
}
} catch (IOException e) {
log.error(e.getMessage());
}
}
2.6、完整代码实现
因为业务需求需要对接多个ftp,所以这里就对ftp进行了配置选择
@Slf4j
@Component
public class FtpUtil {
private static FTPClient ftpClient;
private static FtpProperties properties;
@Autowired
public void setProperties(FtpProperties properties){
FtpUtil.properties = properties;
}
private final static String UTF8 = "UTF-8";
private final static String GBK = "GBK";
/**
*@Author:
*@Desc: 初始化ftp,连接ftp
*@params:[]
*/
public static boolean initFtpClient(String serverType){
FtpInfo fTpInfo = null;
List<FtpInfo> fTpInfos = properties.getFtpInfos();
for(FtpInfo f : fTpInfos){
if(f.getServerType().equals(serverType)){
fTpInfo = f;
}
}
boolean isSuccess = false;
if(fTpInfo==null){
return false;
}
int reply;
ftpClient = new FTPClient();
try {
//连接Ftp服务器
ftpClient.connect(fTpInfo.getIp(), fTpInfo.getPort());
//登陆Ftp服务器
ftpClient.login(fTpInfo.getUserName(), fTpInfo.getPassword());
//设置编码类型
ftpClient.setControlEncoding(UTF8);
//获取返回码,用于判断是否连接成功
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new BusinessException("服务器连接失败");
} else {
//设置被动模式
ftpClient.enterLocalPassiveMode();
//设置字符模式,解决中文乱码问题
ftpClient.setControlEncoding(GBK);
isSuccess = true;
}
} catch (Exception e) {
log.error(e.getMessage());
}
return isSuccess;
}
/**
*@Author:
*@Desc: 关闭ftp连接
*@params:[]
*/
public static void closeFtpClient() {
try {
//退出登陆
ftpClient.logout();
//检测是否连接Ftp服务器
if (ftpClient.isConnected()) {
//关闭连接
ftpClient.disconnect();
}
} catch (IOException e) {
log.error(e.getMessage());
}
}
/**
*@Author:
*@Desc: 解压gz文件到指定目录
*@params:[fileName]
*/
public static void unGzipFile(String fileName,String localPath) {
try(
//建立gzip解压工作流
GZIPInputStream gzip = new GZIPInputStream(ftpClient.retrieveFileStream(fileName));
FileOutputStream out = new FileOutputStream(localPath);
) {
int num;
byte[] buf=new byte[1024];
while ((num = gzip.read(buf,0,buf.length)) != -1)
{
out.write(buf,0,num);
}
} catch (Exception ex){
log.error(ex.toString());
}
}
/**
*@Author:
*@Desc: 从ftp下载指定文件到本地指定目录
*@params:[path,localPath]
*/
public static boolean downFile(String path,String localPath) throws IOException {
boolean isSuccess = false;
ftpClient.changeWorkingDirectory(path);
File file = new File(localPath);
try(FileOutputStream outputStream = new FileOutputStream(file)) {
isSuccess = ftpClient.retrieveFile(file.getName(),outputStream);
}catch (Exception e){
e.printStackTrace();
}
return isSuccess;
}
}
相应的配置文件,通过serverType进行选择连接FTP服务
配置类