优化 ArchiveFileTree

This commit is contained in:
Glavo 2025-08-02 19:17:54 +08:00
parent 6230b436ad
commit 6c3a924db7
2 changed files with 38 additions and 12 deletions

View File

@ -19,6 +19,9 @@ package org.jackhuang.hmcl.util.tree;
import kala.compress.archivers.ArchiveEntry; import kala.compress.archivers.ArchiveEntry;
import kala.compress.archivers.zip.ZipArchiveReader; import kala.compress.archivers.zip.ZipArchiveReader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnmodifiableView;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
@ -48,7 +51,7 @@ public abstract class ArchiveFileTree<F, E extends ArchiveEntry> implements Clos
} }
protected final F file; protected final F file;
protected final Dir<E> root = new Dir<>(); protected final Dir<E> root = new Dir<>("");
public ArchiveFileTree(F file) { public ArchiveFileTree(F file) {
this.file = file; this.file = file;
@ -62,7 +65,7 @@ public abstract class ArchiveFileTree<F, E extends ArchiveEntry> implements Clos
return root; return root;
} }
public void addEntry(E entry) throws IOException { protected void addEntry(E entry) throws IOException {
String[] path = entry.getName().split("/"); String[] path = entry.getName().split("/");
Dir<E> dir = root; Dir<E> dir = root;
@ -78,7 +81,7 @@ public abstract class ArchiveFileTree<F, E extends ArchiveEntry> implements Clos
throw new IOException("A file and a directory have the same name: " + entry.getName()); throw new IOException("A file and a directory have the same name: " + entry.getName());
} }
dir = dir.subDirs.computeIfAbsent(item, name -> new Dir<>()); dir = dir.subDirs.computeIfAbsent(item, Dir::new);
} }
if (entry.isDirectory()) { if (entry.isDirectory()) {
@ -113,16 +116,33 @@ public abstract class ArchiveFileTree<F, E extends ArchiveEntry> implements Clos
public abstract void close() throws IOException; public abstract void close() throws IOException;
public static final class Dir<E extends ArchiveEntry> { public static final class Dir<E extends ArchiveEntry> {
E entry; private final String name;
private E entry;
final Map<String, Dir<E>> subDirs = new HashMap<>(); final Map<String, Dir<E>> subDirs = new HashMap<>();
final Map<String, E> files = new HashMap<>(); final Map<String, E> files = new HashMap<>();
public Map<String, Dir<E>> getSubDirs() { public Dir(String name) {
this.name = name;
}
public boolean isRoot() {
return name.isEmpty();
}
public @NotNull String getName() {
return name;
}
public @Nullable E getEntry() {
return entry;
}
public @NotNull @UnmodifiableView Map<String, Dir<E>> getSubDirs() {
return subDirs; return subDirs;
} }
public Map<String, E> getFiles() { public @NotNull @UnmodifiableView Map<String, E> getFiles() {
return files; return files;
} }
} }

View File

@ -19,6 +19,7 @@ package org.jackhuang.hmcl.util.tree;
import kala.compress.archivers.zip.ZipArchiveEntry; import kala.compress.archivers.zip.ZipArchiveEntry;
import kala.compress.archivers.zip.ZipArchiveReader; import kala.compress.archivers.zip.ZipArchiveReader;
import org.jackhuang.hmcl.util.io.IOUtils;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -27,24 +28,29 @@ import java.io.InputStream;
* @author Glavo * @author Glavo
*/ */
public final class ZipFileTree extends ArchiveFileTree<ZipArchiveReader, ZipArchiveEntry> { public final class ZipFileTree extends ArchiveFileTree<ZipArchiveReader, ZipArchiveEntry> {
private final boolean closeReader;
public ZipFileTree(ZipArchiveReader file) throws IOException { public ZipFileTree(ZipArchiveReader file) throws IOException {
this(file, true);
}
public ZipFileTree(ZipArchiveReader file, boolean closeReader) throws IOException {
super(file); super(file);
this.closeReader = closeReader;
try { try {
for (ZipArchiveEntry zipArchiveEntry : file.getEntries()) { for (ZipArchiveEntry zipArchiveEntry : file.getEntries()) {
addEntry(zipArchiveEntry); addEntry(zipArchiveEntry);
} }
} catch (Throwable e) { } catch (Throwable e) {
try { if (closeReader)
file.close(); IOUtils.closeQuietly(file, e);
} catch (Throwable e2) {
e.addSuppressed(e2);
}
throw e; throw e;
} }
} }
@Override @Override
public void close() throws IOException { public void close() throws IOException {
if (closeReader)
file.close(); file.close();
} }