Skip to content

Commit 05c5b53

Browse files
authored
自动探测日志文件编码 (#3863)
1 parent e98c7df commit 05c5b53

3 files changed

Lines changed: 32 additions & 1 deletion

File tree

HMCL/src/main/java/org/jackhuang/hmcl/game/LogExporter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package org.jackhuang.hmcl.game;
1919

20+
import org.jackhuang.hmcl.util.io.IOUtils;
2021
import org.jackhuang.hmcl.util.logging.Logger;
2122
import org.jackhuang.hmcl.util.StringUtils;
2223
import org.jackhuang.hmcl.util.io.Zipper;
@@ -93,7 +94,7 @@ private static void processLogs(Path directory, String fileExtension, String log
9394
if (Files.isRegularFile(file)) {
9495
FileTime time = Files.readAttributes(file, BasicFileAttributes.class).lastModifiedTime();
9596
if (time.toMillis() >= processStartTime) {
96-
try (BufferedReader reader = Files.newBufferedReader(file, OperatingSystem.NATIVE_CHARSET)) {
97+
try (BufferedReader reader = IOUtils.newBufferedReaderMaybeNativeEncoding(file)) {
9798
zipper.putLines(reader.lines().map(Logger::filterForbiddenToken), file.getFileName().toString());
9899
} catch (IOException e) {
99100
LOG.warning("Failed to read log file: " + file, e);

HMCLCore/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dependencies {
1616
api("com.github.steveice10:opennbt:1.5")
1717
api("org.nanohttpd:nanohttpd:2.3.1")
1818
api("org.jsoup:jsoup:1.19.1")
19+
api("org.glavo:chardet:2.5.0")
1920
compileOnlyApi("org.jetbrains:annotations:26.0.1")
2021

2122
if (JavaVersion.current().isJava8) {

HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/IOUtils.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,20 @@
1717
*/
1818
package org.jackhuang.hmcl.util.io;
1919

20+
import org.glavo.chardet.DetectedCharset;
21+
import org.glavo.chardet.UniversalDetector;
22+
2023
import java.io.*;
24+
import java.nio.channels.Channels;
25+
import java.nio.channels.FileChannel;
2126
import java.nio.charset.Charset;
27+
import java.nio.file.Files;
28+
import java.nio.file.Path;
2229
import java.util.zip.GZIPInputStream;
2330

31+
import static java.nio.charset.StandardCharsets.*;
32+
import static org.jackhuang.hmcl.util.platform.OperatingSystem.NATIVE_CHARSET;
33+
2434
/**
2535
* This utility class consists of some util methods operating on InputStream/OutputStream.
2636
*
@@ -33,6 +43,25 @@ private IOUtils() {
3343

3444
public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
3545

46+
public static BufferedReader newBufferedReaderMaybeNativeEncoding(Path file) throws IOException {
47+
if (NATIVE_CHARSET == UTF_8)
48+
return Files.newBufferedReader(file);
49+
50+
FileChannel channel = FileChannel.open(file);
51+
try {
52+
long oldPosition = channel.position();
53+
DetectedCharset detectedCharset = UniversalDetector.detectCharset(channel);
54+
Charset charset = detectedCharset != null && detectedCharset.isSupported()
55+
&& (detectedCharset.getCharset() == UTF_8 || detectedCharset.getCharset() == US_ASCII)
56+
? UTF_8 : NATIVE_CHARSET;
57+
channel.position(oldPosition);
58+
return new BufferedReader(new InputStreamReader(Channels.newInputStream(channel), charset));
59+
} catch (Throwable e) {
60+
closeQuietly(channel, e);
61+
throw e;
62+
}
63+
}
64+
3665
/**
3766
* Read all bytes to a buffer from given input stream. The stream will not be closed.
3867
*

0 commit comments

Comments
 (0)