代码清理与修复 UI 卡顿资源占用过高的问题 (#1849)
* Lazy initialization of Swing * Load ISRG Root X1 certificate only on Java 8 * Replace JOptionPane with JavaFX Alert * Avoid using java.awt.Desktop * Rewrite TexturesLoader * Optimization SelfDependencyPatcher * fix typo * close #968: Use computeIfAbsent to ensure thread safety * Optimization GameVersion::minecraftVersion * code cleanup * Set the initial capacity of readFullyWithoutClosing * code cleanup * Mark inner classes as static if possible * Cache version icon * Code cleanup * Fix ListView scrolling performance issues * DatapackListPage::items * Replace OutputStream with FileChannel::write
This commit is contained in:
@@ -253,7 +253,7 @@ public class OAuth {
|
||||
DEVICE,
|
||||
}
|
||||
|
||||
public class Result {
|
||||
public static final class Result {
|
||||
private final String accessToken;
|
||||
private final String refreshToken;
|
||||
|
||||
@@ -282,7 +282,7 @@ public class OAuth {
|
||||
@SerializedName("verification_uri")
|
||||
public String verificationURI;
|
||||
|
||||
// Life time in seconds for device_code and user_code
|
||||
// Lifetime in seconds for device_code and user_code
|
||||
@SerializedName("expires_in")
|
||||
public int expiresIn;
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
||||
import org.jackhuang.hmcl.util.io.HttpServer;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.*;
|
||||
@@ -80,8 +79,7 @@ public class YggdrasilServer extends HttpServer {
|
||||
}
|
||||
|
||||
private Response profiles(Request request) throws IOException {
|
||||
String body = IOUtils.readFullyAsString(request.getSession().getInputStream(), UTF_8);
|
||||
List<String> names = JsonUtils.fromNonNullJson(body, new TypeToken<List<String>>() {
|
||||
List<String> names = JsonUtils.fromNonNullJsonFully(request.getSession().getInputStream(), new TypeToken<List<String>>() {
|
||||
}.getType());
|
||||
return ok(names.stream().distinct()
|
||||
.map(this::findCharacterByName)
|
||||
|
||||
@@ -240,7 +240,7 @@ public class DefaultCacheRepository extends CacheRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private class LibraryIndex implements Validation {
|
||||
private static final class LibraryIndex implements Validation {
|
||||
private final String name;
|
||||
private final String hash;
|
||||
private final String type;
|
||||
|
||||
@@ -68,8 +68,7 @@ public class ForgeOldInstallTask extends Task<Version> {
|
||||
InputStream stream = zipFile.getInputStream(zipFile.getEntry("install_profile.json"));
|
||||
if (stream == null)
|
||||
throw new ArtifactMalformedException("Malformed forge installer file, install_profile.json does not exist.");
|
||||
String json = IOUtils.readFullyAsString(stream);
|
||||
ForgeInstallProfile installProfile = JsonUtils.fromNonNullJson(json, ForgeInstallProfile.class);
|
||||
ForgeInstallProfile installProfile = JsonUtils.fromNonNullJsonFully(stream, ForgeInstallProfile.class);
|
||||
|
||||
// unpack the universal jar in the installer file.
|
||||
Library forgeLibrary = new Library(installProfile.getInstall().getPath());
|
||||
|
||||
@@ -67,7 +67,7 @@ public class DefaultGameRepository implements GameRepository {
|
||||
|
||||
private File baseDirectory;
|
||||
protected Map<String, Version> versions;
|
||||
private ConcurrentHashMap<File, Optional<String>> gameVersions = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<File, Optional<String>> gameVersions = new ConcurrentHashMap<>();
|
||||
|
||||
public DefaultGameRepository(File baseDirectory) {
|
||||
this.baseDirectory = baseDirectory;
|
||||
@@ -145,19 +145,13 @@ public class DefaultGameRepository implements GameRepository {
|
||||
// This implementation may cause multiple flows against the same version entering
|
||||
// this function, which is accepted because GameVersion::minecraftVersion should
|
||||
// be consistent.
|
||||
File versionJar = getVersionJar(version);
|
||||
if (gameVersions.containsKey(versionJar)) {
|
||||
return gameVersions.get(versionJar);
|
||||
} else {
|
||||
return gameVersions.computeIfAbsent(getVersionJar(version), versionJar -> {
|
||||
Optional<String> gameVersion = GameVersion.minecraftVersion(versionJar);
|
||||
|
||||
if (!gameVersion.isPresent()) {
|
||||
LOG.warning("Cannot find out game version of " + version.getId() + ", primary jar: " + versionJar.toString() + ", jar exists: " + versionJar.exists());
|
||||
}
|
||||
|
||||
gameVersions.put(versionJar, gameVersion);
|
||||
return gameVersion;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,8 +19,6 @@ package org.jackhuang.hmcl.game;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jenkinsci.constant_pool_scanner.ConstantPool;
|
||||
import org.jenkinsci.constant_pool_scanner.ConstantPoolScanner;
|
||||
import org.jenkinsci.constant_pool_scanner.ConstantType;
|
||||
@@ -28,15 +26,15 @@ import org.jenkinsci.constant_pool_scanner.StringConstant;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
@@ -48,9 +46,9 @@ public final class GameVersion {
|
||||
private GameVersion() {
|
||||
}
|
||||
|
||||
private static Optional<String> getVersionFromJson(Path versionJson) {
|
||||
private static Optional<String> getVersionFromJson(InputStream versionJson) {
|
||||
try {
|
||||
Map<?, ?> version = JsonUtils.fromNonNullJson(FileUtils.readText(versionJson), Map.class);
|
||||
Map<?, ?> version = JsonUtils.fromNonNullJsonFully(versionJson, Map.class);
|
||||
return tryCast(version.get("name"), String.class);
|
||||
} catch (IOException | JsonParseException e) {
|
||||
LOG.log(Level.WARNING, "Failed to parse version.json", e);
|
||||
@@ -58,7 +56,7 @@ public final class GameVersion {
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<String> getVersionOfClassMinecraft(byte[] bytecode) throws IOException {
|
||||
private static Optional<String> getVersionOfClassMinecraft(InputStream bytecode) throws IOException {
|
||||
ConstantPool pool = ConstantPoolScanner.parse(bytecode, ConstantType.STRING);
|
||||
|
||||
return StreamSupport.stream(pool.list(StringConstant.class).spliterator(), false)
|
||||
@@ -68,7 +66,7 @@ public final class GameVersion {
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private static Optional<String> getVersionFromClassMinecraftServer(byte[] bytecode) throws IOException {
|
||||
private static Optional<String> getVersionFromClassMinecraftServer(InputStream bytecode) throws IOException {
|
||||
ConstantPool pool = ConstantPoolScanner.parse(bytecode, ConstantType.STRING);
|
||||
|
||||
List<String> list = StreamSupport.stream(pool.list(StringConstant.class).spliterator(), false)
|
||||
@@ -94,23 +92,29 @@ public final class GameVersion {
|
||||
if (file == null || !file.exists() || !file.isFile() || !file.canRead())
|
||||
return Optional.empty();
|
||||
|
||||
try (FileSystem gameJar = CompressingUtils.createReadOnlyZipFileSystem(file.toPath())) {
|
||||
Path versionJson = gameJar.getPath("version.json");
|
||||
if (Files.exists(versionJson)) {
|
||||
Optional<String> result = getVersionFromJson(versionJson);
|
||||
try (ZipFile gameJar = new ZipFile(file)) {
|
||||
ZipEntry versionJson = gameJar.getEntry("version.json");
|
||||
if (versionJson != null) {
|
||||
Optional<String> result = getVersionFromJson(gameJar.getInputStream(versionJson));
|
||||
if (result.isPresent())
|
||||
return result;
|
||||
}
|
||||
|
||||
Path minecraft = gameJar.getPath("net/minecraft/client/Minecraft.class");
|
||||
if (Files.exists(minecraft)) {
|
||||
Optional<String> result = getVersionOfClassMinecraft(Files.readAllBytes(minecraft));
|
||||
if (result.isPresent())
|
||||
return result;
|
||||
ZipEntry minecraft = gameJar.getEntry("net/minecraft/client/Minecraft.class");
|
||||
if (minecraft != null) {
|
||||
try (InputStream is = gameJar.getInputStream(minecraft)) {
|
||||
Optional<String> result = getVersionOfClassMinecraft(is);
|
||||
if (result.isPresent())
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
ZipEntry minecraftServer = gameJar.getEntry("net/minecraft/server/MinecraftServer.class");
|
||||
if (minecraftServer != null) {
|
||||
try (InputStream is = gameJar.getInputStream(minecraftServer)) {
|
||||
return getVersionFromClassMinecraftServer(is);
|
||||
}
|
||||
}
|
||||
Path minecraftServer = gameJar.getPath("net/minecraft/server/MinecraftServer.class");
|
||||
if (Files.exists(minecraftServer))
|
||||
return getVersionFromClassMinecraftServer(Files.readAllBytes(minecraftServer));
|
||||
return Optional.empty();
|
||||
} catch (IOException e) {
|
||||
return Optional.empty();
|
||||
|
||||
@@ -67,7 +67,7 @@ public final class StringArgument implements Argument {
|
||||
return argument;
|
||||
}
|
||||
|
||||
public class Serializer implements JsonSerializer<StringArgument> {
|
||||
public static final class Serializer implements JsonSerializer<StringArgument> {
|
||||
@Override
|
||||
public JsonElement serialize(StringArgument src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src.getArgument());
|
||||
|
||||
@@ -20,7 +20,6 @@ package org.jackhuang.hmcl.mod;
|
||||
import com.google.gson.JsonParseException;
|
||||
import org.jackhuang.hmcl.util.Immutable;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
@@ -112,7 +111,7 @@ public final class LiteModMetadata {
|
||||
ZipEntry entry = zipFile.getEntry("litemod.json");
|
||||
if (entry == null)
|
||||
throw new IOException("File " + modFile + "is not a LiteLoader mod.");
|
||||
LiteModMetadata metadata = JsonUtils.GSON.fromJson(IOUtils.readFullyAsString(zipFile.getInputStream(entry)), LiteModMetadata.class);
|
||||
LiteModMetadata metadata = JsonUtils.fromJsonFully(zipFile.getInputStream(entry), LiteModMetadata.class);
|
||||
if (metadata == null)
|
||||
throw new IOException("Mod " + modFile + " `litemod.json` is malformed.");
|
||||
return new LocalModFile(modManager, modManager.getLocalMod(metadata.getName(), ModLoaderType.LITE_LOADER), modFile, metadata.getName(), new LocalModFile.Description(metadata.getDescription()), metadata.getAuthor(),
|
||||
|
||||
@@ -26,10 +26,10 @@ import org.jackhuang.hmcl.game.LaunchOptions;
|
||||
import org.jackhuang.hmcl.mod.*;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@@ -66,8 +66,8 @@ public final class McbbsModpackProvider implements ModpackProvider {
|
||||
config.getManifest().injectLaunchOptions(builder);
|
||||
}
|
||||
|
||||
private static Modpack fromManifestFile(String json, Charset encoding) throws IOException, JsonParseException {
|
||||
McbbsModpackManifest manifest = JsonUtils.fromNonNullJson(json, McbbsModpackManifest.class);
|
||||
private static Modpack fromManifestFile(InputStream json, Charset encoding) throws IOException, JsonParseException {
|
||||
McbbsModpackManifest manifest = JsonUtils.fromNonNullJsonFully(json, McbbsModpackManifest.class);
|
||||
return manifest.toModpack(encoding);
|
||||
}
|
||||
|
||||
@@ -75,11 +75,11 @@ public final class McbbsModpackProvider implements ModpackProvider {
|
||||
public Modpack readManifest(ZipFile zip, Path file, Charset encoding) throws IOException, JsonParseException {
|
||||
ZipArchiveEntry mcbbsPackMeta = zip.getEntry("mcbbs.packmeta");
|
||||
if (mcbbsPackMeta != null) {
|
||||
return fromManifestFile(IOUtils.readFullyAsString(zip.getInputStream(mcbbsPackMeta)), encoding);
|
||||
return fromManifestFile(zip.getInputStream(mcbbsPackMeta), encoding);
|
||||
}
|
||||
ZipArchiveEntry manifestJson = zip.getEntry("manifest.json");
|
||||
if (manifestJson != null) {
|
||||
return fromManifestFile(IOUtils.readFullyAsString(zip.getInputStream(manifestJson)), encoding);
|
||||
return fromManifestFile(zip.getInputStream(manifestJson), encoding);
|
||||
}
|
||||
throw new IOException("`mcbbs.packmeta` or `manifest.json` cannot be found");
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipFile;
|
||||
import org.jackhuang.hmcl.util.Immutable;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@@ -60,8 +59,7 @@ public final class MultiMCManifest {
|
||||
ZipArchiveEntry mmcPack = zipFile.getEntry(rootEntryName + "mmc-pack.json");
|
||||
if (mmcPack == null)
|
||||
return null;
|
||||
String json = IOUtils.readFullyAsString(zipFile.getInputStream(mmcPack));
|
||||
MultiMCManifest manifest = JsonUtils.fromNonNullJson(json, MultiMCManifest.class);
|
||||
MultiMCManifest manifest = JsonUtils.fromNonNullJsonFully(zipFile.getInputStream(mmcPack), MultiMCManifest.class);
|
||||
if (manifest.getComponents() == null)
|
||||
throw new IOException("mmc-pack.json malformed.");
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ public abstract class FetchTask<T> extends Task<T> {
|
||||
CACHED
|
||||
}
|
||||
|
||||
protected class DownloadState {
|
||||
protected static final class DownloadState {
|
||||
private final int startPosition;
|
||||
private final int endPosition;
|
||||
private final int currentPosition;
|
||||
@@ -272,9 +272,7 @@ public abstract class FetchTask<T> extends Task<T> {
|
||||
}
|
||||
}
|
||||
|
||||
protected class DownloadMission {
|
||||
|
||||
|
||||
protected static final class DownloadMission {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ package org.jackhuang.hmcl.task;
|
||||
import javafx.application.Platform;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.threadPool;
|
||||
@@ -61,10 +60,6 @@ public final class Schedulers {
|
||||
return Platform::runLater;
|
||||
}
|
||||
|
||||
public static Executor swing() {
|
||||
return SwingUtilities::invokeLater;
|
||||
}
|
||||
|
||||
public static Executor defaultScheduler() {
|
||||
return ForkJoinPool.commonPool();
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@ import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
@@ -54,7 +54,7 @@ public class CacheRepository {
|
||||
private Path cacheDirectory;
|
||||
private Path indexFile;
|
||||
private Map<String, ETagItem> index;
|
||||
private Map<String, Storage> storages = new HashMap<>();
|
||||
private final Map<String, Storage> storages = new HashMap<>();
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
public void changeDirectory(Path commonDir) {
|
||||
@@ -293,9 +293,8 @@ public class CacheRepository {
|
||||
ETagIndex indexOnDisk = JsonUtils.fromMaybeMalformedJson(new String(IOUtils.readFullyWithoutClosing(Channels.newInputStream(channel)), UTF_8), ETagIndex.class);
|
||||
Map<String, ETagItem> newIndex = joinETagIndexes(indexOnDisk == null ? null : indexOnDisk.eTag, index.values());
|
||||
channel.truncate(0);
|
||||
OutputStream os = Channels.newOutputStream(channel);
|
||||
ETagIndex writeTo = new ETagIndex(newIndex.values());
|
||||
IOUtils.write(JsonUtils.GSON.toJson(writeTo).getBytes(UTF_8), os);
|
||||
channel.write(ByteBuffer.wrap(JsonUtils.GSON.toJson(writeTo).getBytes(UTF_8)));
|
||||
this.index = newIndex;
|
||||
} finally {
|
||||
lock.release();
|
||||
@@ -303,7 +302,7 @@ public class CacheRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private class ETagIndex {
|
||||
private static final class ETagIndex {
|
||||
private final Collection<ETagItem> eTag;
|
||||
|
||||
public ETagIndex() {
|
||||
@@ -315,7 +314,7 @@ public class CacheRepository {
|
||||
}
|
||||
}
|
||||
|
||||
private class ETagItem {
|
||||
private static final class ETagItem {
|
||||
private final String url;
|
||||
private final String eTag;
|
||||
private final String hash;
|
||||
@@ -429,8 +428,7 @@ public class CacheRepository {
|
||||
if (indexOnDisk == null) indexOnDisk = new HashMap<>();
|
||||
indexOnDisk.putAll(storage);
|
||||
channel.truncate(0);
|
||||
OutputStream os = Channels.newOutputStream(channel);
|
||||
IOUtils.write(JsonUtils.GSON.toJson(storage).getBytes(UTF_8), os);
|
||||
channel.write(ByteBuffer.wrap(JsonUtils.GSON.toJson(storage).getBytes(UTF_8)));
|
||||
this.storage = indexOnDisk;
|
||||
} finally {
|
||||
lock.release();
|
||||
|
||||
@@ -23,7 +23,11 @@ import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
@@ -44,6 +48,18 @@ public final class JsonUtils {
|
||||
private JsonUtils() {
|
||||
}
|
||||
|
||||
public static <T> T fromJsonFully(InputStream json, Class<T> classOfT) throws IOException, JsonParseException {
|
||||
try (InputStreamReader reader = new InputStreamReader(json, StandardCharsets.UTF_8)) {
|
||||
return GSON.fromJson(reader, classOfT);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T fromJsonFully(InputStream json, Type type) throws IOException, JsonParseException {
|
||||
try (InputStreamReader reader = new InputStreamReader(json, StandardCharsets.UTF_8)) {
|
||||
return GSON.fromJson(reader, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T fromNonNullJson(String json, Class<T> classOfT) throws JsonParseException {
|
||||
T parsed = GSON.fromJson(json, classOfT);
|
||||
if (parsed == null)
|
||||
@@ -58,6 +74,24 @@ public final class JsonUtils {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
public static <T> T fromNonNullJsonFully(InputStream json, Class<T> classOfT) throws IOException, JsonParseException {
|
||||
try (InputStreamReader reader = new InputStreamReader(json, StandardCharsets.UTF_8)) {
|
||||
T parsed = GSON.fromJson(reader, classOfT);
|
||||
if (parsed == null)
|
||||
throw new JsonParseException("Json object cannot be null.");
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T fromNonNullJsonFully(InputStream json, Type type) throws IOException, JsonParseException {
|
||||
try (InputStreamReader reader = new InputStreamReader(json, StandardCharsets.UTF_8)) {
|
||||
T parsed = GSON.fromJson(reader, type);
|
||||
if (parsed == null)
|
||||
throw new JsonParseException("Json object cannot be null.");
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T fromMaybeMalformedJson(String json, Class<T> classOfT) throws JsonParseException {
|
||||
try {
|
||||
return GSON.fromJson(json, classOfT);
|
||||
|
||||
@@ -231,7 +231,7 @@ public final class CompressingUtils {
|
||||
* @return the plain text content of given file.
|
||||
*/
|
||||
public static String readTextZipEntry(ZipFile zipFile, String name) throws IOException {
|
||||
return IOUtils.readFullyAsString(zipFile.getInputStream(zipFile.getEntry(name)), StandardCharsets.UTF_8);
|
||||
return IOUtils.readFullyAsString(zipFile.getInputStream(zipFile.getEntry(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,7 +244,7 @@ public final class CompressingUtils {
|
||||
*/
|
||||
public static String readTextZipEntry(Path zipFile, String name, Charset encoding) throws IOException {
|
||||
try (ZipFile s = openZipFile(zipFile, encoding)) {
|
||||
return IOUtils.readFullyAsString(s.getInputStream(s.getEntry(name)), StandardCharsets.UTF_8);
|
||||
return IOUtils.readFullyAsString(s.getInputStream(s.getEntry(name)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,10 +27,11 @@ import java.net.HttpURLConnection;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
public class HttpMultipartRequest implements Closeable {
|
||||
private static final String endl = "\r\n";
|
||||
|
||||
private final String boundary = "*****" + System.currentTimeMillis() + "*****";
|
||||
private final HttpURLConnection urlConnection;
|
||||
private final ByteArrayOutputStream stream;
|
||||
private final String endl = "\r\n";
|
||||
|
||||
public HttpMultipartRequest(HttpURLConnection urlConnection) throws IOException {
|
||||
this.urlConnection = urlConnection;
|
||||
@@ -69,7 +70,7 @@ public class HttpMultipartRequest implements Closeable {
|
||||
addLine("--" + boundary + "--");
|
||||
urlConnection.setRequestProperty("Content-Length", "" + stream.size());
|
||||
try (OutputStream os = urlConnection.getOutputStream()) {
|
||||
IOUtils.write(stream.toByteArray(), os);
|
||||
stream.writeTo(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -143,7 +142,7 @@ public abstract class HttpRequest {
|
||||
return getStringWithRetry(() -> {
|
||||
HttpURLConnection con = createConnection();
|
||||
con = resolveConnection(con);
|
||||
return IOUtils.readFullyAsString(con.getInputStream(), StandardCharsets.UTF_8);
|
||||
return IOUtils.readFullyAsString(con.getInputStream());
|
||||
}, retryTimes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package org.jackhuang.hmcl.util.io;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* This utility class consists of some util methods operating on InputStream/OutputStream.
|
||||
@@ -40,7 +39,7 @@ public final class IOUtils {
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public static byte[] readFullyWithoutClosing(InputStream stream) throws IOException {
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream(Math.max(stream.available(), 32));
|
||||
copyTo(stream, result);
|
||||
return result.toByteArray();
|
||||
}
|
||||
@@ -54,7 +53,7 @@ public final class IOUtils {
|
||||
*/
|
||||
public static ByteArrayOutputStream readFully(InputStream stream) throws IOException {
|
||||
try (InputStream is = stream) {
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream(Math.max(is.available(), 32));
|
||||
copyTo(is, result);
|
||||
return result;
|
||||
}
|
||||
@@ -68,18 +67,6 @@ public final class IOUtils {
|
||||
return readFully(stream).toString("UTF-8");
|
||||
}
|
||||
|
||||
public static String readFullyAsString(InputStream stream, Charset charset) throws IOException {
|
||||
return readFully(stream).toString(charset.name());
|
||||
}
|
||||
|
||||
public static void write(String text, OutputStream outputStream) throws IOException {
|
||||
write(text.getBytes(), outputStream);
|
||||
}
|
||||
|
||||
public static void write(byte[] bytes, OutputStream outputStream) throws IOException {
|
||||
copyTo(new ByteArrayInputStream(bytes), outputStream);
|
||||
}
|
||||
|
||||
public static void copyTo(InputStream src, OutputStream dest) throws IOException {
|
||||
copyTo(src, dest, new byte[DEFAULT_BUFFER_SIZE]);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jackhuang.hmcl.util.Pair;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@@ -176,7 +175,7 @@ public final class NetworkUtils {
|
||||
public static String doGet(URL url) throws IOException {
|
||||
HttpURLConnection con = createHttpConnection(url);
|
||||
con = resolveConnection(con);
|
||||
return IOUtils.readFullyAsString(con.getInputStream(), StandardCharsets.UTF_8);
|
||||
return IOUtils.readFullyAsString(con.getInputStream());
|
||||
}
|
||||
|
||||
public static String doPost(URL u, Map<String, String> params) throws IOException {
|
||||
@@ -210,13 +209,13 @@ public final class NetworkUtils {
|
||||
public static String readData(HttpURLConnection con) throws IOException {
|
||||
try {
|
||||
try (InputStream stdout = con.getInputStream()) {
|
||||
return IOUtils.readFullyAsString(stdout, UTF_8);
|
||||
return IOUtils.readFullyAsString(stdout);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
try (InputStream stderr = con.getErrorStream()) {
|
||||
if (stderr == null)
|
||||
throw e;
|
||||
return IOUtils.readFullyAsString(stderr, UTF_8);
|
||||
return IOUtils.readFullyAsString(stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class CrashReportAnalyzerTest {
|
||||
@@ -35,7 +34,7 @@ public class CrashReportAnalyzerTest {
|
||||
if (is == null) {
|
||||
throw new IllegalStateException("Resource not found: " + path);
|
||||
}
|
||||
return IOUtils.readFullyAsString(is, StandardCharsets.UTF_8);
|
||||
return IOUtils.readFullyAsString(is);
|
||||
}
|
||||
|
||||
private CrashReportAnalyzer.Result findResultByRule(List<CrashReportAnalyzer.Result> results, CrashReportAnalyzer.Rule rule) {
|
||||
|
||||
Reference in New Issue
Block a user