mirror of
https://github.com/HMCL-dev/HMCL
synced 2026-08-19 22:23:08 -04:00
修复导出日志文件时文件为空的问题 (#6649)
This commit is contained in:
parent
a0d1fa8f38
commit
cf21cf4a3c
4 changed files with 70 additions and 4 deletions
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import kala.encdet.EncodingDetector;
|
||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||
import org.jackhuang.hmcl.util.io.Zipper;
|
||||
import org.jackhuang.hmcl.util.logging.Logger;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
|
|
@ -90,7 +90,7 @@ public final class LogExporter {
|
|||
for (Path file : stream) {
|
||||
if (Files.isRegularFile(file)) {
|
||||
if (logMatcher == null || logMatcher.matches(file)) {
|
||||
try (BufferedReader reader = EncodingDetector.MODERN_WEB.newBufferedReader(file)) {
|
||||
try (BufferedReader reader = IOUtils.newBufferedReaderMaybeNativeEncoding(file)) {
|
||||
zipper.putLines(reader.lines().map(Logger::filterForbiddenToken), file.getFileName().toString());
|
||||
} catch (IOException e) {
|
||||
LOG.warning("Failed to read log file: " + file, e);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import javafx.scene.layout.VBox;
|
|||
import javafx.scene.text.Text;
|
||||
import javafx.scene.text.TextFlow;
|
||||
import javafx.stage.Stage;
|
||||
import kala.encdet.EncodingDetector;
|
||||
import org.jackhuang.hmcl.Metadata;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.game.*;
|
||||
|
|
@ -49,6 +48,7 @@ import org.jackhuang.hmcl.util.Lang;
|
|||
import org.jackhuang.hmcl.util.Log4jLevel;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.logging.Logger;
|
||||
import org.jackhuang.hmcl.util.platform.*;
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ public class GameCrashWindow extends Stage {
|
|||
|
||||
String log;
|
||||
try {
|
||||
log = EncodingDetector.MODERN_WEB.readString(latestLog);
|
||||
log = FileUtils.readTextMaybeNativeEncoding(latestLog);
|
||||
} catch (IOException e) {
|
||||
LOG.warning("Failed to read logs/latest.log", e);
|
||||
return pair(new HashSet<CrashReportAnalyzer.Result>(), new HashSet<String>());
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package org.jackhuang.hmcl.util.io;
|
||||
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import kala.encdet.EncodingDetector;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.function.ExceptionalConsumer;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
|
|
@ -38,6 +39,8 @@ import java.util.*;
|
|||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
/**
|
||||
|
|
@ -235,6 +238,22 @@ public final class FileUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static String readTextMaybeNativeEncoding(Path file) throws IOException {
|
||||
byte[] bytes = Files.readAllBytes(file);
|
||||
|
||||
if (OperatingSystem.NATIVE_CHARSET == UTF_8)
|
||||
return new String(bytes, UTF_8);
|
||||
|
||||
EncodingDetector detector = EncodingDetector.MODERN_WEB;
|
||||
EncodingDetector.@Nullable Encoding bestEncoding = detector.detect(bytes).bestEncoding();
|
||||
@Nullable Charset detectedCharset = bestEncoding != null ? bestEncoding.approximateCharset() : null;
|
||||
|
||||
if (detectedCharset != null && (detectedCharset == UTF_8 || detectedCharset == US_ASCII))
|
||||
return new String(bytes, UTF_8);
|
||||
else
|
||||
return new String(bytes, OperatingSystem.NATIVE_CHARSET);
|
||||
}
|
||||
|
||||
public static void deleteDirectory(Path directory) throws IOException {
|
||||
if (!Files.exists(directory))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -17,11 +17,20 @@
|
|||
*/
|
||||
package org.jackhuang.hmcl.util.io;
|
||||
|
||||
import kala.encdet.EncodingDetector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static org.jackhuang.hmcl.util.platform.OperatingSystem.NATIVE_CHARSET;
|
||||
|
||||
/**
|
||||
* This utility class consists of some util methods operating on InputStream/OutputStream.
|
||||
|
|
@ -35,6 +44,44 @@ public final class IOUtils {
|
|||
|
||||
public static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
|
||||
|
||||
public static BufferedReader newBufferedReaderMaybeNativeEncoding(Path file) throws IOException {
|
||||
if (NATIVE_CHARSET == UTF_8)
|
||||
return Files.newBufferedReader(file);
|
||||
|
||||
FileChannel channel = FileChannel.open(file);
|
||||
try {
|
||||
long oldPosition = channel.position();
|
||||
long size = channel.size();
|
||||
|
||||
EncodingDetector detector = EncodingDetector.MODERN_WEB;
|
||||
|
||||
int bufferSize = (int) Math.max(Math.min(size - oldPosition, detector.maxBytes()), 8192L);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
|
||||
|
||||
//noinspection StatementWithEmptyBody
|
||||
while (buffer.hasRemaining() && channel.read(buffer) > 0) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
buffer.flip();
|
||||
Charset charset;
|
||||
if (buffer.remaining() == 0) {
|
||||
charset = UTF_8;
|
||||
} else {
|
||||
EncodingDetector.@Nullable Encoding encoding = detector.detect(buffer).bestEncoding();
|
||||
Charset detectedCharset = encoding != null ? encoding.approximateCharset() : null;
|
||||
charset = detectedCharset != null && (detectedCharset == UTF_8 || detectedCharset == US_ASCII)
|
||||
? UTF_8
|
||||
: NATIVE_CHARSET;
|
||||
}
|
||||
channel.position(oldPosition);
|
||||
return new BufferedReader(new InputStreamReader(Channels.newInputStream(channel), charset));
|
||||
} catch (Throwable e) {
|
||||
closeQuietly(channel, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] readFully(InputStream stream) throws IOException {
|
||||
try (stream) {
|
||||
return stream.readAllBytes();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue