导出日志时允许重名文件 (#4733)
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user