有一个名为juniversalchardet的库可以帮助你猜测正确编码。它最近已更新,目前位于GitHub上:
https://github.com/albfernandez/juniversalchardet
然而,并没有绝对可靠的工具来检测编码,因为有很多未知的东西:
1. 这个文件是文本还是PNG?
2. 它存储在(1,...,k,...,n)位编码中吗?
3. 使用了哪种k位编码?
通过计算不常用控制字符的数量,可以进行一些猜测。当一个文件包含许多控制符号时,你可能选择了错误的编码。(然后尝试下一个)
Juniversalchardet尝试多种并且更成功的方式来确定编码(甚至包括中文)。它还提供了方便的方法来打开一个阅读器,从文件中选择正确的编码:
(代码片段取自https://github.com/albfernandez/juniversalchardet#creating-a-reader-with-correct-encoding并进行了修改)
import org.mozilla.universalchardet.ReaderFactory;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
public class TestCreateReaderFromFile {
public static void main (String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java TestCreateReaderFromFile FILENAME");
System.exit(1);
}
Reader reader = null;
try {
File file = new File(args[0]);
reader = ReaderFactory.createBufferedReader(file);
String line;
while((line=reader.readLine())!=null){
System.out.println(line);
}
}
finally {
if (reader != null) {
reader.close();
}
}
}
}
编辑:添加了ScannerFactory
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Scanner;
import org.mozilla.universalchardet.UniversalDetector;
import org.mozilla.universalchardet.UnicodeBOMInputStream;
public final class ScannerFactory {
private ScannerFactory() {
throw new AssertionError("No instances allowed");
}
public static Scanner createScanner(File file, Charset defaultCharset) throws IOException {
Charset cs = Objects.requireNonNull(defaultCharset, "defaultCharset must be not null");
String detectedEncoding = UniversalDetector.detectCharset(file);
if (detectedEncoding != null) {
cs = Charset.forName(detectedEncoding);
}
if (!cs.toString().contains("UTF")) {
return new Scanner(file, cs.name());
}
Path path = file.toPath();
return new Scanner(new UnicodeBOMInputStream(new BufferedInputStream(Files.newInputStream(path))), cs.name());
}
public static Scanner createScanner(File file) throws IOException {
return createScanner(file, Charset.defaultCharset());
}
}
while(scanner.hasNextLine()) line = scanner.nextLine();
如果这样做不起作用,那么如果你只是在读取行,可以尝试使用普通的缓冲读取器方式。 - locus2k