Skip to content

Commit

Permalink
Optimize file operation
Browse files Browse the repository at this point in the history
  • Loading branch information
XiaoPangxie732 committed Aug 23, 2024
1 parent 562573b commit 68cf047
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ public void decompile(String decompilerName, @Nullable Path incrementalJar) {
ObjectSet<Path> libs = options.bundledLibs().<ObjectSet<Path>>map(ObjectOpenHashSet::new).orElseGet(() ->
DownloadingUtil.downloadLibraries(options.version(), libDownloadPath));
if (incrementalJar != null && decompiler.getSourceType() == IDecompiler.SourceType.DIRECTORY) {
try (FileSystem incrementalFs = JarUtil.createZipFs(incrementalJar)) {
try (FileSystem incrementalFs = JarUtil.createZipFs(incrementalJar);
Stream<Path> paths = FileUtil.iterateFiles(incrementalFs.getPath(""))) {
var toDecompile = deobfuscator.toDecompile;
ObjectOpenHashSet<String> possibleInnerClasses = new ObjectOpenHashSet<>();
ObjectOpenHashSet<String> maybeRemoved = new ObjectOpenHashSet<>();
FileUtil.iterateFiles(incrementalFs.getPath("")).forEach(p -> {
paths.forEach(p -> {
String path = p.toString();
if (path.endsWith(".class")) {
String fileName = p.getFileName().toString();
Expand Down Expand Up @@ -224,8 +225,9 @@ private void preprocess(Path inputJar) {
} else throw new IllegalArgumentException("Why multiple versions in a bundle?");
ObjectOpenHashSet<Path> libs = new ObjectOpenHashSet<>();
try (Stream<String> lines = Files.lines(metaInf.resolve("libraries.list"))) {
Path libraries = metaInf.resolve("libraries");
lines.forEach(line -> {
Path lib = metaInf.resolve("libraries").resolve(line.split("\t")[2]);
Path lib = libraries.resolve(line.split("\t")[2]);
FileUtil.copyFile(lib, extractDir);
libs.add(extractDir.resolve(lib.getFileName().toString()));
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cn.maxpixel.mcdecompiler.common.app.util;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;

public class DirectorySpliterator implements Spliterator<Path> {// TODO: implement this later
private final DirectoryStream<Path> stream;
private Iterator<Path> it;

public DirectorySpliterator(Path dir) throws IOException {
this.stream = Files.newDirectoryStream(dir);
this.it = stream.iterator();
}

@Override
public boolean tryAdvance(Consumer<? super Path> action) {
if (it.hasNext()) {
action.accept(it.next());
return true;
}
try {
stream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return false;
}

@Override
public void forEachRemaining(Consumer<? super Path> action) {
}

@Override
public Spliterator<Path> trySplit() {
return null;
}

@Override
public long estimateSize() {
return Long.MAX_VALUE;
}

@Override
public int characteristics() {
return DISTINCT | NONNULL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
Expand All @@ -56,6 +57,7 @@ public class DownloadingUtil {
public static final Proxy INTERNAL_PROXY = Constants.IS_DEV ?
new Proxy(Proxy.Type.HTTP, new InetSocketAddress(1080)) : // Just for internal testing.
Proxy.NO_PROXY;
private static final OpenOption[] OPEN_OPTIONS = {CREATE, WRITE, TRUNCATE_EXISTING};

public static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
.proxy(new ProxySelector() {
Expand Down Expand Up @@ -90,7 +92,7 @@ public static CompletableFuture<Path> downloadJar(@NotNull String version, @NotN
LOGGER.info("Downloading {} {} jar...", id, type);
return HTTP_CLIENT.sendAsync(
HttpRequest.newBuilder(URI.create(download.get("url").getAsString())).build(),
HttpResponse.BodyHandlers.ofFile(FileUtil.ensureFileExist(p), WRITE, TRUNCATE_EXISTING)
HttpResponse.BodyHandlers.ofFile(FileUtil.makeParentDirs(p), OPEN_OPTIONS)
).thenApply(HttpResponse::body);
} else return CompletableFuture.completedFuture(p);
}).whenComplete((p, ex) -> {
Expand All @@ -116,7 +118,7 @@ public static CompletableFuture<BufferedReader> downloadMapping(@NotNull String
LOGGER.info("Downloading {} {} mapping...", id, type);
return HTTP_CLIENT.sendAsync(
HttpRequest.newBuilder(URI.create(mappings.get("url").getAsString())).build(),
HttpResponse.BodyHandlers.ofFile(FileUtil.ensureFileExist(p), WRITE, TRUNCATE_EXISTING)
HttpResponse.BodyHandlers.ofFile(FileUtil.makeParentDirs(p), OPEN_OPTIONS)
).thenApply(HttpResponse::body);
} else return CompletableFuture.completedFuture(p);
}).thenApply(LambdaUtil.unwrap(Files::newBufferedReader, LambdaUtil::rethrowAsCompletion));
Expand All @@ -134,11 +136,9 @@ public static InputStream getRemoteResource(@NotNull Path localPath, @NotNull UR
try {
if (!FileUtil.verify(Objects.requireNonNull(localPath), HTTP_CLIENT.send(HttpRequest.newBuilder(remoteHash)
.build(), HttpResponse.BodyHandlers.ofString()).body())) {
FileUtil.deleteIfExists(localPath);
LOGGER.debug("Downloading the resource");
FileUtil.ensureFileExist(localPath);
HTTP_CLIENT.send(HttpRequest.newBuilder(remoteResource).build(),
HttpResponse.BodyHandlers.ofFile(localPath, WRITE, TRUNCATE_EXISTING));
HttpResponse.BodyHandlers.ofFile(FileUtil.makeParentDirs(localPath), OPEN_OPTIONS));
}
} catch (InterruptedException e) {
LOGGER.fatal("Download process interrupted", e);
Expand Down Expand Up @@ -171,7 +171,7 @@ public static InputStream getRemoteResource(@NotNull Path localPath, @NotNull UR
LOGGER.debug("Downloading {}", url);
try {
HTTP_CLIENT.send(HttpRequest.newBuilder(URI.create(url)).build(),
HttpResponse.BodyHandlers.ofFile(file, CREATE, WRITE, TRUNCATE_EXISTING));
HttpResponse.BodyHandlers.ofFile(file, OPEN_OPTIONS));
} catch (IOException e) {
LOGGER.fatal("Error downloading files", e);
throw Utils.wrapInRuntime(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

package cn.maxpixel.mcdecompiler.common.app.util;

import cn.maxpixel.mcdecompiler.common.util.LambdaUtil;
import cn.maxpixel.mcdecompiler.common.util.Utils;
import cn.maxpixel.rewh.logging.LogManager;
import cn.maxpixel.rewh.logging.Logger;
Expand All @@ -35,7 +34,6 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

Expand Down Expand Up @@ -116,28 +114,26 @@ public static Path requireExist(@NotNull Path p) {
return p;
}

public static Path ensureFileExist(@NotNull Path p) {
if (Files.notExists(p)) {
try {
Path parent = p.getParent();
if (parent != null) Files.createDirectories(parent);
Files.createFile(p);
} catch (IOException e) {
throw Utils.wrapInRuntime(e);
}
public static Path makeParentDirs(@NotNull Path p) {
try {
Path parent = p.getParent();
if (parent != null) Files.createDirectories(parent);
} catch (IOException e) {
throw Utils.wrapInRuntime(e);
}
return p;
}

public static Stream<Path> iterateFiles(@NotNull Path path) {
try {
DirectoryStream<Path> ds = Files.newDirectoryStream(path);
return StreamSupport.stream(ds.spliterator(), true)
.mapMulti((Path p, Consumer<Path> cons) -> {
if (Files.isDirectory(p)) try (var s = iterateFiles(p)) {
s.sequential().forEach(cons);
} else cons.accept(p);
}).onClose(LambdaUtil.unwrap(ds::close));
try {// TODO: implement a custom spliterator later
// DirectoryStream<Path> ds = Files.newDirectoryStream(path);
// return StreamSupport.stream(ds.spliterator(), true)
// .mapMulti((Path p, Consumer<Path> cons) -> {
// if (Files.isDirectory(p)) try (var s = iterateFiles(p)) {
// s.sequential().forEach(cons);
// } else cons.accept(p);
// }).onClose(LambdaUtil.unwrap(ds::close));
return Files.walk(path).parallel().filter(Files::isRegularFile);
} catch (IOException e) {
LOGGER.fatal("Error iterating files", e);
throw Utils.wrapInRuntime(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ protected Deobfuscator(DeobfuscationOptions options) {
public Deobfuscator<T> deobfuscate(Path source, Path target) throws IOException {
LOGGER.info("Deobfuscating...");
Files.deleteIfExists(target);
Files.createDirectories(target.getParent());
try (FileSystem fs = JarUtil.createZipFs(FileUtil.requireExist(source));
FileSystem targetFs = JarUtil.createZipFs(target, true);
FileSystem targetFs = JarUtil.createZipFs(FileUtil.makeParentDirs(target), true);
Stream<Path> paths = FileUtil.iterateFiles(fs.getPath(""))) {
Set<String> extraClasses = options.extraClasses;
boolean deobfAll = extraClasses.contains("*") || extraClasses.contains("*all*");
Expand All @@ -58,8 +57,9 @@ public Deobfuscator<T> deobfuscate(Path source, Path target) throws IOException
(extraClassesNotEmpty && extraClasses.stream().anyMatch(k::startsWith));
}), true);
options.extraJars.forEach(jar -> {
try (FileSystem jarFs = JarUtil.createZipFs(jar)) {
FileUtil.iterateFiles(jarFs.getPath("")).filter(p -> p.toString().endsWith(".class")).forEach(info);
try (FileSystem jarFs = JarUtil.createZipFs(jar);
Stream<Path> s = FileUtil.iterateFiles(jarFs.getPath(""))) {
s.filter(p -> p.toString().endsWith(".class")).forEach(info);
} catch (IOException e) {
LOGGER.warn("Error reading extra jar: {}", jar, e);
}
Expand All @@ -81,13 +81,13 @@ public Deobfuscator<T> deobfuscate(Path source, Path target) throws IOException
synchronized (toDecompile) {
toDecompile.add(mapped);
}
try (OutputStream os = Files.newOutputStream(FileUtil.ensureFileExist(targetFs.getPath(mapped)))) {
try (OutputStream os = Files.newOutputStream(FileUtil.makeParentDirs(targetFs.getPath(mapped)))) {
os.write(writer.toByteArray());
}
} else if (options.includeOthers) {
if (pathString.endsWith(".SF") || pathString.endsWith(".RSA")) return;
try (InputStream inputStream = Files.newInputStream(path);
OutputStream os = Files.newOutputStream(FileUtil.ensureFileExist(targetFs.getPath(pathString)))) {
OutputStream os = Files.newOutputStream(FileUtil.makeParentDirs(targetFs.getPath(pathString)))) {
if (path.endsWith("META-INF/MANIFEST.MF")) {
Manifest man = new Manifest(inputStream);
man.getEntries().clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public String mapMethodName(String owner, String name, String descriptor) {
return name;
}

private Optional<String[]> processSuperMethod(String owner, String name, String descriptor) {
private Optional<String[]> processSuperMethod(String owner, String name, String descriptor) {// TODO: Optimize this
return Optional.ofNullable(eci.getSuperNames(owner))
.flatMap(superNames -> {
String nameAndDesc = name.concat(descriptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.StringJoiner;

public final class ForgeFlowerAbstractParametersRecorder {
Expand All @@ -51,9 +50,7 @@ public boolean isRecording() {

public void endRecord(@NotNull Path writeTo) throws IOException {
if (!recording) throw new IllegalStateException("Record not started yet");
FileUtil.deleteIfExists(writeTo);
Files.writeString(FileUtil.ensureFileExist(writeTo), String.join("\n", generated),
StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
Files.writeString(FileUtil.makeParentDirs(writeTo), String.join("\n", generated));
LOGGER.debug("Saved record to {}", writeTo);
recording = false;
LOGGER.debug("Ended record");
Expand Down

0 comments on commit 68cf047

Please sign in to comment.