將目標目錄打包壓縮到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;
}