【发布时间】:2011-11-29 03:55:49
【问题描述】:
我想从流中获取编码。
第一种方法 - 使用 InputStreamReader。
但它总是返回操作系统编码。
InputStreamReader reader = new InputStreamReader(new FileInputStream("aa.rar"));
System.out.println(reader.getEncoding());
输出:GBK
第二种方法 - 使用 UniversalDetector。
但它总是返回 null。
FileInputStream input = new FileInputStream("aa.rar");
UniversalDetector detector = new UniversalDetector(null);
byte[] buf = new byte[4096];
int nread;
while ((nread = input.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread);
}
// (3)
detector.dataEnd();
// (4)
String encoding = detector.getDetectedCharset();
if (encoding != null) {
System.out.println("Detected encoding = " + encoding);
} else {
System.out.println("No encoding detected.");
}
// (5)
detector.reset();
输出:空
我怎样才能得到正确的? :(
【问题讨论】:
-
InputStreamReader 将始终使用平台编码。它不会尝试检测文件中的编码。您通过 UniversalDetector 运行什么类型的文件?在您的示例中,您使用了 RAR 文件,它是一种压缩的二进制格式。首先尝试使用简单的 ASCII 文本文件。
-
嗨,我更改了文件类型,'Fortunes.txt' 输出:未检测到编码
-
它似乎没有检测到没有 BOM 的“标准”UTF-8 或 UTF-16,但它适用于带有 BOM 的 UTF-16。也许考虑使用不同的库进行字符集检测? This link 可能会有所帮助。
-
通过检查文本数据来检测编码是不可靠的猜测。您确实需要在某处将编码指定为元数据。
-
@Michael Borwardt:但在许多情况下,您确实没有有任何元数据指定编码,并且您确实没有有任何规格告诉您在哪个编码您需要解析的txt文件将被编码。在这些情况下,诸如www-archive.mozilla.org/projects/intl/… 之类的“猜测”(使用字母频率以及许多其他启发式方法)似乎是相当“科学”的猜测。一切并不总是非黑即白。当您没有元数据时,您不会说:“我需要元数据”,但您会努力工作并编写(或重用)检测器。