将目标目录打包压缩到zip包中,通过jdk1.7的Files.walkFileTree原理实现,参考代码如下:
/**
* 将目标文件或者文件夹压缩到zip中
*
* @param zipOutpusStream zip输出流
* @param target 需要压缩的目标目录
* @param ignoreEntryNames 忽略压缩目录
* @throws IOException IOException
*/
public static void zip(OutputStream zipOutpusStream, Path target, List<Path> ignoreEntryNames) throws IOException {
ZipOutputStream out = new ZipOutputStream(zipOutpusStream);
Files.walkFileTree(target, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new ZipDirectoryVisitor(out, target, ignoreEntryNames));
if (out != null) {
out.close();
}
}
package xxx.nio;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* ZIP包输出访问器
*
* @author 许畅
* @since JDK1.7
* @version 2019年4月8日 许畅 新建
*/
public class ZipDirectoryVisitor extends SimpleFileVisitor<Path> {
/** zip输出流 */
private ZipOutputStream out;
/** zip包中存储相对路径 */
private Path relativePath;
/** zip包中需要忽略的entry名称 */
private List<Path> ignoreEntryNames;
/**
* 构造方法
*
* @param out ZIP输出流
* @param relativePath ZIP包存储相对路径
*/
public ZipDirectoryVisitor(ZipOutputStream out, Path relativePath) {
setOut(out);
setRelativePath(relativePath);
}
/**
* 构造方法
*
* @param out ZIP输出流
* @param relativePath ZIP包存储相对路径
* @param ignoreEntryNames zip包中需要忽略的entry名称
*/
public ZipDirectoryVisitor(ZipOutputStream out, Path relativePath, List<Path> ignoreEntryNames) {
setOut(out);
setRelativePath(relativePath);
setIgnoreEntryNames(ignoreEntryNames);
}
/**
* 访问文件
*
* @param file 文件路径
* @param attributes 属性
* @return FileVisitResult
* @throws IOException IO异常
*/
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
Path entryName = relativePath.relativize(file);
if (ignoreEntryNames == null || !ignoreEntryNames.contains(entryName)) {
addEntry(file.toFile(), entryName);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path directory, BasicFileAttributes attributes) throws IOException {
return FileVisitResult.CONTINUE;
}
/**
* 添加ZIP包的entry
*
* @param inFile ZIP输入文件
* @param entryName ZIP的文件名
* @throws IOException IOException
*/
private void addEntry(File inFile, Path entryName) throws IOException {
ZipEntry entry = new ZipEntry(entryName.toString());
out.putNextEntry(entry);
int len = 0;
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(inFile);
while ((len = fis.read(buffer)) > 0) {
out.write(buffer, 0, len);
out.flush();
}
out.closeEntry();
fis.close();
}
/**
* @return 获取 out属性值
*/
public ZipOutputStream getOut() {
return out;
}
/**
* @param out 设置 out 属性值为参数值 out
*/
public void setOut(ZipOutputStream out) {
this.out = out;
}
/**
* @return 获取 relativePath属性值
*/
public Path getRelativePath() {
return relativePath;
}
/**
* @param relativePath 设置 relativePath 属性值为参数值 relativePath
*/
public void setRelativePath(Path relativePath) {
this.relativePath = relativePath;
}
/**
* @return 获取 ignoreEntryNames属性值
*/
public List<Path> getIgnoreEntryNames() {
return ignoreEntryNames;
}
/**
* @param ignoreEntryNames 设置 ignoreEntryNames 属性值为参数值 ignoreEntryNames
*/
public void setIgnoreEntryNames(List<Path> ignoreEntryNames) {
this.ignoreEntryNames = ignoreEntryNames;
}
}
将zip包解压到指定文件夹,直接通过jdk io实现,参考代码如下:
/**
* 将zip包解压到目标目录
*
* @param zipInputstream zip输入流
* @param destDir 需要解压的目标目录
* @param ignorePatterns 忽略解压目录
* @throws IOException IOException
*/
public static void unzip(InputStream zipInputstream, Path destDir, List<String> ignorePatterns) throws IOException {
if (!Files.exists(destDir)) {
Files.createDirectories(destDir);
}
byte[] buffer = new byte[1024];
ZipInputStream zis = new ZipInputStream(zipInputstream);
ZipEntry zipEntry = zis.getNextEntry();
AntPathMatcher antPathMatcher = new AntPathMatcher();
while (zipEntry != null) {
if (isIgnoreMatch(ignorePatterns, zipEntry.getName(), antPathMatcher)) {
zipEntry = zis.getNextEntry();
continue;
}
Path destFile = destDir.resolve(zipEntry.getName());
if (zipEntry.isDirectory()) {
if (!Files.exists(destFile)) {
Files.createDirectories(destFile);
}
} else {
if (!Files.exists(destFile) && !Files.exists(destFile.getParent())) {
// 创建上级文件夹
Files.createDirectories(destFile.getParent());
}
FileOutputStream fos = new FileOutputStream(destFile.toFile());
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
zipEntry = zis.getNextEntry();
}
}
zis.closeEntry();
zis.close();
}
/**
* @param ignorePatterns 忽略正则
* @param entryName 目录名称
* @param antPathMatcher AntPathMatcher
* @return 是否忽略
*/
private static boolean isIgnoreMatch(List<String> ignorePatterns, String entryName, AntPathMatcher antPathMatcher) {
if (ignorePatterns != null) {
for (String ignorePattern : ignorePatterns) {
if (antPathMatcher.match(ignorePattern, entryName)) {
return true;
}
}
}
return false;
}