Java:如何确定流的正确charset编码

问题

参考以下主题:Java App : Unable to read iso-8859-1 encoded file correctly

以编程方式确定输入流/文件的正确字符集编码的最佳方法是什么?

我尝试过使用以下内容:

File in =  new File(args[0]);
InputStreamReader r = new InputStreamReader(new FileInputStream(in));
System.out.println(r.getEncoding());

但是在我知道用ISO8859_1编码的文件中,上面的代码产生了ASCII,这是不正确的,并且不允许我正确地将文件的内容呈现回控制台。


#1 热门回答(92 赞)

你无法确定任意字节流的编码。这是编码的本质。编码意味着字节值与其表示之间的映射。所以每个编码"都可能"是正确的。

ThegetEncoding()方法将返回为流设置的编码(读取JavaDoc)。它不会猜测你的编码。

一些流告诉你使用哪种编码来创建它们:XML,HTML。但不是任意字节流。

无论如何,如果必须,你可以尝试自己猜测编码。每种语言都有一个共同的频率。在英语中,char e经常出现,但ê似乎很少出现。在ISO-8859-1流中,通常没有0x00字符。但是UTF-16流有很多。

或者:你可以询问用户。我已经看过应用程序以不同的编码为你呈现文件的片段,并要求你选择"正确"的文件。


#2 热门回答(62 赞)

我使用过这个库,类似于jchardet,用于检测Java中的编码:http://code.google.com/p/juniversalchardet/


#3 热门回答(31 赞)

看看这个:http://site.icu-project.org/(icu4j)他们有用于检测来自IOStream的字符集的库可能很简单,如下所示:

BufferedInputStream bis = new BufferedInputStream(input);
CharsetDetector cd = new CharsetDetector();
cd.setText(bis);
CharsetMatch cm = cd.detect();

if (cm != null) {
   reader = cm.getReader();
   charset = cm.getName();
}else {
   throw new UnsupportedCharsetException()
}