自动探测日志文件编码 (#3863)
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.game;
|
package org.jackhuang.hmcl.game;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||||
import org.jackhuang.hmcl.util.logging.Logger;
|
import org.jackhuang.hmcl.util.logging.Logger;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.io.Zipper;
|
import org.jackhuang.hmcl.util.io.Zipper;
|
||||||
@@ -93,7 +94,7 @@ public final class LogExporter {
|
|||||||
if (Files.isRegularFile(file)) {
|
if (Files.isRegularFile(file)) {
|
||||||
FileTime time = Files.readAttributes(file, BasicFileAttributes.class).lastModifiedTime();
|
FileTime time = Files.readAttributes(file, BasicFileAttributes.class).lastModifiedTime();
|
||||||
if (time.toMillis() >= processStartTime) {
|
if (time.toMillis() >= processStartTime) {
|
||||||
try (BufferedReader reader = Files.newBufferedReader(file, OperatingSystem.NATIVE_CHARSET)) {
|
try (BufferedReader reader = IOUtils.newBufferedReaderMaybeNativeEncoding(file)) {
|
||||||
zipper.putLines(reader.lines().map(Logger::filterForbiddenToken), file.getFileName().toString());
|
zipper.putLines(reader.lines().map(Logger::filterForbiddenToken), file.getFileName().toString());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.warning("Failed to read log file: " + file, e);
|
LOG.warning("Failed to read log file: " + file, e);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ dependencies {
|
|||||||
api("com.github.steveice10:opennbt:1.5")
|
api("com.github.steveice10:opennbt:1.5")
|
||||||
api("org.nanohttpd:nanohttpd:2.3.1")
|
api("org.nanohttpd:nanohttpd:2.3.1")
|
||||||
api("org.jsoup:jsoup:1.19.1")
|
api("org.jsoup:jsoup:1.19.1")
|
||||||
|
api("org.glavo:chardet:2.5.0")
|
||||||
compileOnlyApi("org.jetbrains:annotations:26.0.1")
|
compileOnlyApi("org.jetbrains:annotations:26.0.1")
|
||||||
|
|
||||||
if (JavaVersion.current().isJava8) {
|
if (JavaVersion.current().isJava8) {
|
||||||
|
|||||||
@@ -17,10 +17,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.io;
|
package org.jackhuang.hmcl.util.io;
|
||||||
|
|
||||||
|
import org.glavo.chardet.DetectedCharset;
|
||||||
|
import org.glavo.chardet.UniversalDetector;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.zip.GZIPInputStream;
|
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.
|
* This utility class consists of some util methods operating on InputStream/OutputStream.
|
||||||
*
|
*
|
||||||
@@ -33,6 +43,25 @@ public final class IOUtils {
|
|||||||
|
|
||||||
public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
|
public static final int DEFAULT_BUFFER_SIZE = 8 * 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();
|
||||||
|
DetectedCharset detectedCharset = UniversalDetector.detectCharset(channel);
|
||||||
|
Charset charset = detectedCharset != null && detectedCharset.isSupported()
|
||||||
|
&& (detectedCharset.getCharset() == UTF_8 || detectedCharset.getCharset() == 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all bytes to a buffer from given input stream. The stream will not be closed.
|
* Read all bytes to a buffer from given input stream. The stream will not be closed.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user