从ftp获取文件并生成压缩包
Posted qiaozhuangshi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从ftp获取文件并生成压缩包相关的知识,希望对你有一定的参考价值。
依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.5</version>
</dependency>
可选择多个路径进行压缩
package per.qiao.utils.ftp;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import per.qiao.utils.ioutil.ZipUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* Create by IntelliJ Idea 2018.2
*
* @author: qyp
* Date: 2019-07-18 11:34
*/
public class ZipFtpFileUtil
private final static Logger logger = LoggerFactory.getLogger(ZipFtpFileUtil.class);
/**
* 加载一个非空文件夹
*/
private static void loadFile(FTPClient ftp, String dirPath, ZipOutputStream zos) throws IOException
FTPFile[] ftpFiles = ftp.listFiles();
// 空文件夹
boolean isDir = (ftpFiles == null || ftpFiles.length <= 0)
&& !StringUtils.contains(dirPath, ".");
if (isDir)
zos.putNextEntry(new ZipEntry(dirPath + File.separator));
return;
for (FTPFile f : ftpFiles)
if (f.isFile())
InputStream in = ftp.retrieveFileStream(f.getName());
zos.putNextEntry(new ZipEntry(dirPath + File.separator + f.getName()));
addToZOS(in, zos);
ftp.completePendingCommand();
else
if (ftp.changeWorkingDirectory(f.getName()))
loadFile(ftp, dirPath + File.separator + f.getName(), zos);
// ftp指针移动到上一层
ftp.changeToParentDirectory();
/**
* 切换目录 返回切换的层级数
* @param path
* @param ftp
* @return 切换的层级数
* @throws IOException
*/
private static int exchageDir(String path, FTPClient ftp) throws IOException
// 切换的次数(层级),方便回退
int level = 0;
if (StringUtils.isNotBlank(path))
// 对路径按照 '/' 进行切割,一层一层的进入
String[] pathes = path.split("/");
for (String onepath : pathes)
if (onepath == null || "".equals(onepath.trim()))
continue;
//文件排除
if (onepath.contains("."))
continue;
boolean flagDir = ftp.changeWorkingDirectory(onepath);
if (flagDir)
level ++;
logger.info("成功连接ftp目录:" + ftp.printWorkingDirectory());
else
logger.warn("连接ftp目录失败:" + ftp.printWorkingDirectory());
return level;
/**
* 处理单个文件和空文件夹的情况 处理了返回true 未处理返回false
* 注意:这里是指数组中给的路径直接是文件或者空文件夹的情况
* @param ftp
* @param path 需要压缩的文件(文件夹)路径(相对根)
* @param zos
* @return
* @throws IOException
*/
public static boolean delFile(FTPClient ftp, String path, ZipOutputStream zos) throws IOException
String fileRelativePaht = path;
String[] split = fileRelativePaht.split("/");
int times = exchageDir(path, ftp);
// 是否处理过
boolean isDel = false;
//有父级目录 处理根节点下多级目录下的文件和空文件夹
if (split != null && split.length > 0)
String lastSegmeng = split[split.length - 1];
//path直接是文件
if (lastSegmeng.contains("."))
zos.putNextEntry(new ZipEntry(fileRelativePaht));
addToZOS(ftp.retrieveFileStream(lastSegmeng), zos);
ftp.completePendingCommand();
isDel = true;
else if (ftp.listFiles().length <= 0)
// 空文件夹
zos.putNextEntry(new ZipEntry(fileRelativePaht + File.separator));
isDel = true;
// 如果被处理过(空文件夹或者直接给的文件的路径),退回到根路径(以免污染下次循环的ftp指针)
if (isDel)
for (int i = 0; i < times; i++)
ftp.changeToParentDirectory();
return isDel;
/**
* 添加文件到压缩流
* @param in 输入流(一般就直接是从FTP中获取的)
* @param zos 压缩输出流
* @throws IOException
*/
public static void addToZOS(InputStream in, ZipOutputStream zos) throws IOException
byte[] buf = new byte[1024];
//BufferedOutputStream bzos = new BufferedOutputStream(zos);
try
for (int len; (len = (in.read(buf))) != -1; )
zos.write(buf, 0 , len);
catch (IOException e)
System.out.println("流转换异常");
throw e;
finally
if (in != null)
try
in.close();
catch (IOException e)
System.out.println("关流异常");
e.printStackTrace();
public static FTPClient getFtpClient(String path) throws Exception
String server = "127.0.0.1";
int port = 21;
String username = "test";
String password = "test";
// path = "/FTPStation/";
FTPClient ftpClient = connectServer(server, port, username, password, path);
return ftpClient;
/**
*
* @param server
* @param port
* @param username
* @param password
* @param path 连接的节点(相对根路径的文件夹)
* @return
*/
public static FTPClient connectServer(String server, int port, String username, String password, String path) throws IOException
path = path == null ? "" : path;
FTPClient ftp = new FTPClient();
//下面四行代码必须要,而且不能改变编码格式,否则不能正确下载中文文件
// 如果使用serv-u发布ftp站点,则需要勾掉“高级选项”中的“对所有已收发的路径和文件名使用UTF-8编码”
ftp.setControlEncoding("GBK");
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
ftp.configure(conf);
// 判断ftp是否存在
ftp.connect(server, port);
ftp.setDataTimeout(2 * 60 * 1000);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
ftp.disconnect();
System.out.println(server + "拒绝连接");
//登陆ftp
boolean login = ftp.login(username, password);
if (logger.isDebugEnabled())
if (login)
logger.debug("登陆FTP成功! ip: " + server);
else
logger.debug("登陆FTP失败! ip: " + server);
//根据输入的路径,切换工作目录。这样ftp端的路径就可以使用相对路径了
exchageDir(path, ftp);
return ftp;
public static void main(String[] args) throws Exception
String[] paths = "/CAD/你好.txt", "/CAD/第一层";
String savePath = "e:/temp/zz.zip";
//连接到的节点
String rootDir = "/";
FTPClient ftp = getFtpClient(rootDir);
zipFileByPaths(ftp, savePath, paths);
/**
* 多FTP路径压缩
* @param ftp
* @param savePath
* @param filePaths
* @throws Exception
*/
public static void zipFileByPaths(FTPClient ftp, String savePath, String[] filePaths) throws Exception
try (ZipOutputStream zos = getOutPutStream(savePath))
for (String path : filePaths)
if (delFile(ftp, path, zos))
continue;
loadFile(ftp, path, zos);
zos.flush();
catch (Exception e)
logger.error("多路径文件压缩失败");
e.printStackTrace();
throw e;
/**
* 获取apache的ZipOutputStream流
* @param savePath 保存压缩文件的路径
* @return
* @throws FileNotFoundException 如果保存路径不存在,那么将会抛异常
*/
private static ZipOutputStream getOutPutStream(String savePath) throws FileNotFoundException
//输出的压缩原始文件流fileDir + "\\" + "详情.zip"
FileOutputStream f = new FileOutputStream(new File(savePath));
// 计算和校验文件
CheckedOutputStream csum = new CheckedOutputStream(f, new CRC32());
// 输出的压缩文件流
ZipOutputStream zos = new ZipOutputStream(csum);
zos.setComment("dist文件压缩流");
//设置压缩工具右边的文字编码 防止右边的说明文字乱码
zos.setEncoding(System.getProperty("sun.jnu.encoding"));
return zos;
以上是关于从ftp获取文件并生成压缩包的主要内容,如果未能解决你的问题,请参考以下文章
uniapp文件管理 文件列表 获取媒体文件 图片视频音频文档压缩包文件并实现可删除文件 图片文件列表 视频文件列表 音频文件列表 获取内存卡图片视频音频pdf xlxs docx txt