Java 偵測文字檔案字符編碼的方式如下。
Java讀取文字檔內容到程式中是逐步讀取檔案的位元組為串流輸入,然後依字符編碼(charset encoding)將讀入的位元組串流依照字符集(charset)轉成文字。從程式的角度來看讀進來的字只是一堆位元組,所以無法透過這些位元組得知文字檔的字符編碼。
如果要知道讀取文件的編碼只能透過猜測的方式。目前有相關的函式庫可利用,下面使用juniversalchardet及ICU4J函式庫偵測讀取的文字檔編碼。
下面讀取的hello_big5.txt
內容如下,文件編碼為BIG5。
哈囉你好嗎 衷心感謝 珍重再見 期待再相逢
juniversalchardet
package com.abc.demo;
import org.mozilla.universalchardet.UniversalDetector;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String encoding = detectCharSetEncoding("D:\\hello_big5.txt");
System.out.println(encoding); // BIG5 or WINDOWS-1252
}
/** 使用juniversalchardet偵測文件編碼 */
private static String detectCharSetEncoding(String filePath) {
UniversalDetector detector = new UniversalDetector(null);
try (
FileInputStream fis = new FileInputStream(new File(filePath));
) {
byte[] buf = new byte[1024];
int nread;
while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread);
}
} catch (IOException e) {
e.printStackTrace();
return "";
}
detector.dataEnd();
String encoding = detector.getDetectedCharset();
if (encoding == null) {
return "";
}
return encoding;
}
ICU4J
package com.abc.demo;
import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String encoding = detectCharSetEncoding("D:\\hello_big5.txt");
System.out.println(encoding); // Big5 or ISO-8859-1
}
/** 使用ICU4J偵測文件編碼 */
private static String detectCharSetEncoding(String filePath) {
File file = new File(filePath);
byte[] data = null;
try {
data = FileUtils.readFileToByteArray(file); // Apache Commons IO FileUtils
} catch (IOException e) {
e.printStackTrace();
}
CharsetDetector charsetDetector = new CharsetDetector();
charsetDetector.setText(data);
CharsetMatch charsetMatch = charsetDetector.detect();
String encoding = charsetMatch.getName();
if (encoding == null) {
return "";
}
return encoding;
}
}
但很多字符在不同字符集可能都有相同的編碼,這會讓猜測的結果不準確,例如上面文件內容太短可能無法測到真正的編碼是BIG5,在juniversalchardet測到WINDOWS-1252,在ICU4J測到ISO-8859-1。
沒有留言:
張貼留言