依赖

<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>

可选择多个路径进行压缩

依赖

<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.5</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.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 java.io.File;
import java.io.IOException;
import java.io.InputStream; /**
* Create by IntelliJ Idea 2018.2
*
* @author: qyp
* Date: 2019-07-19 17:10
*/
public class FtpFileZipUtls { private final static Logger logger = LoggerFactory.getLogger(FtpFileZipUtls.class); /**
* 加载一个非空文件夹
*/
private static void loadFile(FTPClient ftp, String dirPath, ZipOutputStream zos) throws IOException { FTPFile[] ftpFiles = ftp.listFiles();
// length小于0用于区分非空文件夹与空文件夹和文件的区别
// 退到上层再进入
if (ftpFiles.length <= 0 && ftp.changeToParentDirectory()) {
logger.info("退回到: " + ftp.printWorkingDirectory());
dirPath = dirPath.replaceAll("\\\\", "/");
boolean b = ftp.changeWorkingDirectory(getFileName(dirPath.substring(dirPath.lastIndexOf("/") + 1)));
logger.info("进入: " + ftp.printWorkingDirectory());
// 是一个空文件夹
if (b && (ftpFiles == null || ftpFiles.length <= 0)) {
zos.putNextEntry(new ZipEntry(getFileName(dirPath) + File.separator));
return;
}
} for (FTPFile f : ftpFiles) {
if (f.isFile()) {
InputStream in = ftp.retrieveFileStream(f.getName());
zos.putNextEntry(new ZipEntry(getFileName(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 sb
* @return
*/
private static void replaceFileName(StringBuilder sb, String onepath) {
sb.replace(sb.indexOf(onepath), sb.indexOf(onepath) + onepath.length(), onepath.replaceAll("\\.", "^^"));
}
/**
* 将文件夹路径中的 ^^ 替换成 .
* @param sb
* @return
*/
private static String getFileName(String sb) {
StringBuilder result = new StringBuilder(sb);
while (result.indexOf("^^") > -1) {
result.replace(result.indexOf("^^"), result.indexOf("^^") + 2, ".");
}
return result.toString();
} /**
* 切换目录 返回切换的层级数
* @param sb
* @param ftp
* @return 切换的层级数
* @throws IOException
*/
private static int exchageDir(StringBuilder sb, FTPClient ftp) throws IOException {
// 计入进入的文件夹的次数,方便回退
int level = 0;
String[] pathes = sb.toString().split("/");
for (int i = 0, len = pathes.length; i < len; i++) {
String onepath = pathes[i];
if (onepath == null || "".equals(onepath.trim())) {
continue;
}
//文件排除
boolean flagDir = ftp.changeWorkingDirectory(onepath);
if (flagDir) {
level++;
if (onepath.contains(".")) {
//把文件夹中的.用^^代替
replaceFileName(sb, onepath);
}
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, StringBuilder path, ZipOutputStream zos) throws IOException { int times = exchageDir(path, ftp); String fileRelativePaht = path.toString();
String[] split = fileRelativePaht.split("/");
// 是否处理过
boolean isDel = false;
//有父级目录
if (split != null && split.length > 0) { String lastSegmeng = split[split.length - 1]; //path直接是文件
if (split[split.length - 1].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(new StringBuilder(path), ftp); return ftp;
} public static void main(String[] args) throws Exception { String[] paths = {"/CAD/你好.txt", "/CAD/1.第一层"};
String savePath = "e:/temp/zz.zip";
//连接到的节点
String rootDir = "/CAD";
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 = ZipUtils.getOutPutStream(savePath)) {
for (String path : filePaths) {
StringBuilder sb = new StringBuilder(path);
//delFile时进入的文件夹的路径(当前需要遍历的文件的路径)
String before = ftp.printWorkingDirectory();
if (delFile(ftp, sb, zos)) {
continue;
}
loadFile(ftp, sb.toString(), zos);
// 文件加载完毕后,需要将ftp的指针退到开始状态
String after = ftp.printWorkingDirectory();
backPath(before, after, ftp);
}
zos.flush();
} catch (Exception e) {
logger.error("多路径文件压缩失败");
e.printStackTrace();
throw e;
}
} /**
* ftp 指针回退
* @param end
* @param start
* @param ftp
* @throws IOException
*/
private static void backPath(String end, String start, FTPClient ftp) throws IOException {
long startTime = System.currentTimeMillis();
do {
if (!end.equals(start) && ftp.changeToParentDirectory()) {
start = ftp.printWorkingDirectory();
}
// 防止意外出现空循环 30s等待时间
if (System.currentTimeMillis() - startTime > 30 * 1000) {
break;
}
} while (!end.equals(start));
}
}

从ftp获取文件并生成压缩包的更多相关文章

  1. Poco之ftp获取文件列表以及下载文件

    #include <iostream>#include <string>#include <vector>#include <algorithm>#in ...

  2. ftpget 从Windows FTP服务端获取文件

    /********************************************************************************* * ftpget 从Windows ...

  3. C#WPF做FTP上传下载获取文件列表

    Xaml.cs: using Microsoft.Win32;using System;using System.Collections.Generic;using System.IO;using S ...

  4. 使用.net FtpWebRequest 实现FTP常用功能 上传 下载 获取文件列表 移动 切换目录 改名 .

    平时根本没时间搞FTP什么的,现在这个项目需要搞FTP,为什么呢,我给大家说下项目背景,我们的一个应用程序上需要上传图片,但是用户部署程序的服务器上不让上传任何东西,给了我们一个FTP账号和密码,让我 ...

  5. SSIS 实例 从Ftp获取多个文件并对数据库进行增量更新。

    整个流程 Step 1 放置一个FTP Task 将远程文件复制到本地 建立FTP链接管理器后 Is LocalPatchVariable 设置为Ture 并创建一个变量设置本地路径 Operatio ...

  6. FTP文件操作之获取文件列表

    前面已经介绍了很多关于FTP对文件的操作,今天再跟大家介绍一个获取文件列表的功能.这个功能应该算是最简单的一个了,它只是获取了一下文件信息,而没有进行实质上的数据传输. 下面是是该功能的核心代码:   ...

  7. C# FTP操作类(获取文件和文件夹列表)

    一.如何获取某一目录下的文件和文件夹列表. 由于FtpWebRequest类只提供了WebRequestMethods.Ftp.ListDirectory方式和WebRequestMethods.Ft ...

  8. ftp获取远程Pdf文件

    此程序需要安装ftp服务器,安装adobe reader(我这里使用的adobe reader9.0) 1.部署ftp服务器 将ftp的权限设置为允许匿名访问,部署完成 2.安装adobe reade ...

  9. java版ftp简易客户端(可以获取文件的名称及文件大小)

    java版ftp简易客户端(可以获取文件的名称及文件大小) package com.ccb.ftp; import java.io.IOException; import java.net.Socke ...

随机推荐

  1. lnmp一键安装包 多PHP版本使用教程

    ./install.sh mphp 多PHP版本只支持LNMP模式,LNMPA.LAMP模式下不支持!要使用多PHP先安装多PHP版本,在lnmp1.4源码目录下运行:./install.sh mph ...

  2. onenote架设在局域网服务器

    1.服务器端工作 1.1.在局域网服务器磁盘建个 文件夹,命名为 abc 1.2.右键共享,添加用户everyone 权限设置为可读写 不需要安装onenote 2.客户端工作 2.1.在客户端服务器 ...

  3. JEECG Hibernate 自动更新 持久化

    Hibernate不调用update却自动更新 - 七郎 - 博客园http://www.cnblogs.com/yangy608/p/4073941.html hibernate自动更新持久化类的问 ...

  4. nginx高级玩法之根据来源ip分流

    author :headsen chen date :   2019-08-15  16:37:05 notice :个人原创 需求:根据不同的请求的来源ip实现分流到不同的后端上去 方法一:1,在s ...

  5. 算法习题---5.6团体队列(Uva540)

    一:题目 有t个队伍的人正在排队,每次新来一个人,如果他有队友在排队,那他可以插队,直接排到他的队伍的末尾.如果没有队伍在前面,那么他直接排在长队的末尾 ENQUEUE x 将编号x的队员入队 DEQ ...

  6. 【Mybatis】MyBatis之插件开发(十)

    MyBatis插件开发原理 MyBatis采用责任链模式,通过动态代理组织多个插件(拦截器),通过这些插件可以改变MyBatis的默认行为(诸如SQL重写之类的),由于插件会深入到MyBatis的核心 ...

  7. 汉字转拼音插件:LM-PinYin.js

    CDN:http://dtdxrk.github.io/jsPlug/pinyin/LM-PinYin.js demo演示地址:http://dtdxrk.github.io/jsPlug/pinyi ...

  8. ELK之Kibana的可视化监控报警插件sentinl的配置

    参考:https://www.bbsmax.com/A/gGdXbgXmJ4/ https://www.deathearth.com/333.html  https://www.cnblogs.com ...

  9. 12、OpenCV实现图像的直方图处理

    1.直方图 一幅图像由不同灰度值的像素组成,图像中灰度的分布情况是该图像的一个重要特征.图像的灰度直方图就描述了图像中灰度分布情况,能够很直观的展示出图像中各个灰度级所占的多少.图像的灰度直方图是灰度 ...

  10. 【GStreamer开发】GStreamer播放教程05——色彩平衡

    目标 亮度,对比度,色度和饱和度都是常见的视频调节参数,也是GStreamer里面设置色彩平衡的参数.本教程将展示: 如何发现可用的色彩平衡通道 如何改变它们 介绍 <GStreamer基础教程 ...