add support for zip file

This commit is contained in:
申劭明 2021-10-18 09:58:56 +00:00 committed by Gitee
parent 612c2d8a98
commit c9bb53dd03

View File

@ -1,7 +1,11 @@
package cn.hutool.core.io.file.visitor; package cn.hutool.core.io.file.visitor;
import cn.hutool.core.io.file.PathUtil; import cn.hutool.core.io.file.PathUtil;
import cn.hutool.core.util.StrUtil;
import com.sun.nio.zipfs.ZipFileSystem;
import com.sun.nio.zipfs.ZipPath;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.CopyOption; import java.nio.file.CopyOption;
import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileAlreadyExistsException;
@ -23,6 +27,8 @@ public class CopyVisitor extends SimpleFileVisitor<Path> {
private final Path source; private final Path source;
private final Path target; private final Path target;
private boolean isTargetCreated; private boolean isTargetCreated;
private final boolean isZipFile;
private String dirRoot = null;
private final CopyOption[] copyOptions; private final CopyOption[] copyOptions;
/** /**
@ -38,15 +44,28 @@ public class CopyVisitor extends SimpleFileVisitor<Path> {
} }
this.source = source; this.source = source;
this.target = target; this.target = target;
this.isZipFile = target instanceof ZipPath;
this.copyOptions = copyOptions; this.copyOptions = copyOptions;
} }
@Override @Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException { throws IOException {
initTarget(); final Path targetDir;
// 将当前目录相对于源路径转换为相对于目标路径 if (isZipFile) {
final Path targetDir = target.resolve(source.relativize(dir)); ZipPath zipPath = (ZipPath) target;
ZipFileSystem fileSystem = zipPath.getFileSystem();
if (dirRoot == null) {
targetDir = fileSystem.getPath(dir.getFileName().toString());
dirRoot = dir.getFileName().toString() + File.separator;
} else {
targetDir = fileSystem.getPath(dirRoot, StrUtil.subAfter(dir.toString(), dirRoot, false));
}
} else {
initTarget();
// 将当前目录相对于源路径转换为相对于目标路径
targetDir = target.resolve(source.relativize(dir));
}
try { try {
Files.copy(dir, targetDir, copyOptions); Files.copy(dir, targetDir, copyOptions);
} catch (FileAlreadyExistsException e) { } catch (FileAlreadyExistsException e) {
@ -59,8 +78,17 @@ public class CopyVisitor extends SimpleFileVisitor<Path> {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException { throws IOException {
initTarget(); if (isZipFile) {
Files.copy(file, target.resolve(source.relativize(file)), copyOptions); if (dirRoot == null) {
Files.copy(file, target, copyOptions);
} else {
ZipPath zipPath = (ZipPath) target;
Files.copy(file, zipPath.getFileSystem().getPath(dirRoot, StrUtil.subAfter(file.toString(), dirRoot, false)), copyOptions);
}
} else {
initTarget();
Files.copy(file, target.resolve(source.relativize(file)), copyOptions);
}
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }