我有一个文本文件,它可以是ANSI(带有ISO-8859-2字符集),UTF-8,UCS-2 Big或Little Endian。
有没有办法检测文件的编码以正确读取它?
或者是否可以在不给出编码的情况下读取文件? (它按原样读取文件)
(有几个程序可以检测和转换文本文件的编码/格式。)
答案 0 :(得分:11)
是的,有很多方法可以进行字符编码检测,特别是在Java中。看一下基于Mozilla算法的jchardet。还有cpdetector和IBM的一个名为ICU4j的项目。我会看看后者,因为它似乎比其他两个更可靠。它们基于二进制文件的统计分析工作,ICU4j还将提供它检测到的字符编码的置信度,因此您可以在上面的情况下使用它。它运作得很好。
答案 1 :(得分:9)
UTF-8和UCS-2 / UTF-16可以通过文件开头的byte order mark轻松区分。如果存在,则该文件处于该编码状态相当不错的选择 - 但这不是一个确定的问题。您可能还会在其中一种编码中发现文件 ,但没有字节顺序标记。
我对ISO-8859-2了解不多,但如果每个文件几乎都是该编码中的有效文本文件,我不会感到惊讶。你能做的最好的就是启发式检查。实际上,Wikipedia page谈论它会表明只有字节0x7f无效。
不知道“按原样”读取文件但是还没有文本输出 - 文件是字节的序列,所以你必须应用字符编码才能解码这些字节变成人物。
答案 2 :(得分:2)
您可以使用ICU4J(http://icu-project.org/apiref/icu4j/)
这是我的代码:
String charset = "ISO-8859-1"; //Default chartset, put whatever you want
byte[] fileContent = null;
FileInputStream fin = null;
//create FileInputStream object
fin = new FileInputStream(file.getPath());
/*
* Create byte array large enough to hold the content of the file.
* Use File.length to determine size of the file in bytes.
*/
fileContent = new byte[(int) file.length()];
/*
* To read content of the file in byte array, use
* int read(byte[] byteArray) method of java FileInputStream class.
*
*/
fin.read(fileContent);
byte[] data = fileContent;
CharsetDetector detector = new CharsetDetector();
detector.setText(data);
CharsetMatch cm = detector.detect();
if (cm != null) {
int confidence = cm.getConfidence();
System.out.println("Encoding: " + cm.getName() + " - Confidence: " + confidence + "%");
//Here you have the encode name and the confidence
//In my case if the confidence is > 50 I return the encode, else I return the default value
if (confidence > 50) {
charset = cm.getName();
}
}
记得把所有的try catch都需要它。
我希望这适合你。
答案 3 :(得分:0)