导出日志时允许重名文件 (#4733)

This commit is contained in:
Glavo
2026-01-23 22:41:07 +08:00
committed by GitHub
parent 165d77df30
commit 95eeae4c42
3 changed files with 49 additions and 22 deletions

View File

@@ -25,6 +25,8 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
@@ -39,13 +41,15 @@ public final class Zipper implements Closeable {
private final ZipOutputStream zos;
private final byte[] buffer = new byte[IOUtils.DEFAULT_BUFFER_SIZE];
private final Set<String> entryNames;
public Zipper(Path zipFile) throws IOException {
this(zipFile, StandardCharsets.UTF_8);
this(zipFile, false);
}
public Zipper(Path zipFile, Charset encoding) throws IOException {
this.zos = new ZipOutputStream(Files.newOutputStream(zipFile), encoding);
public Zipper(Path zipFile, boolean allowDuplicateEntry) throws IOException {
this.zos = new ZipOutputStream(Files.newOutputStream(zipFile), StandardCharsets.UTF_8);
this.entryNames = allowDuplicateEntry ? new HashSet<>() : null;
}
private static String normalize(String path) {
@@ -57,6 +61,20 @@ public final class Zipper implements Closeable {
return path;
}
private ZipEntry newEntry(String name) throws IOException {
if (entryNames == null || name.endsWith("/") || entryNames.add(name))
return new ZipEntry(name);
for (int i = 1; i < 10; i++) {
String newName = name + "." + i;
if (entryNames.add(newName)) {
return new ZipEntry(newName);
}
}
throw new ZipException("duplicate entry: " + name);
}
private static String resolve(String dir, String file) {
if (dir.isEmpty()) return file;
if (file.isEmpty()) return dir;
@@ -71,7 +89,7 @@ public final class Zipper implements Closeable {
/**
* Compress all the files in sourceDir
*
* @param source the file in basePath to be compressed
* @param source the file in basePath to be compressed
* @param targetDir the path of the directory in this zip file.
*/
public void putDirectory(Path source, String targetDir) throws IOException {
@@ -81,9 +99,9 @@ public final class Zipper implements Closeable {
/**
* Compress all the files in sourceDir
*
* @param source the file in basePath to be compressed
* @param source the file in basePath to be compressed
* @param targetDir the path of the directory in this zip file.
* @param filter returns false if you do not want that file or directory
* @param filter returns false if you do not want that file or directory
*/
public void putDirectory(Path source, String targetDir, ExceptionalPredicate<String, IOException> filter) throws IOException {
String root = normalize(targetDir);
@@ -118,16 +136,12 @@ public final class Zipper implements Closeable {
});
}
public void putFile(File file, String path) throws IOException {
putFile(file.toPath(), path);
}
public void putFile(Path file, String path) throws IOException {
path = normalize(path);
BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
ZipEntry entry = new ZipEntry(attrs.isDirectory() ? path + "/" : path);
ZipEntry entry = newEntry(attrs.isDirectory() ? path + "/" : path);
entry.setCreationTime(attrs.creationTime());
entry.setLastAccessTime(attrs.lastAccessTime());
entry.setLastModifiedTime(attrs.lastModifiedTime());
@@ -149,13 +163,13 @@ public final class Zipper implements Closeable {
}
public void putStream(InputStream in, String path) throws IOException {
zos.putNextEntry(new ZipEntry(normalize(path)));
zos.putNextEntry(newEntry(normalize(path)));
IOUtils.copyTo(in, zos, buffer);
zos.closeEntry();
}
public OutputStream putStream(String path) throws IOException {
zos.putNextEntry(new ZipEntry(normalize(path)));
zos.putNextEntry(newEntry(normalize(path)));
return new OutputStream() {
public void write(int b) throws IOException {
zos.write(b);
@@ -180,7 +194,7 @@ public final class Zipper implements Closeable {
}
public void putLines(Stream<String> lines, String path) throws IOException {
zos.putNextEntry(new ZipEntry(normalize(path)));
zos.putNextEntry(newEntry(normalize(path)));
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(zos));
@@ -205,7 +219,7 @@ public final class Zipper implements Closeable {
}
public void putTextFile(String text, Charset encoding, String path) throws IOException {
zos.putNextEntry(new ZipEntry(normalize(path)));
zos.putNextEntry(newEntry(normalize(path)));
zos.write(text.getBytes(encoding));
zos.closeEntry();
}