記一次項(xiàng)目中遇到的坑。線上系統(tǒng)有解析CSV與txt文本文件的需求,文本文件包含中文砍聊,同時(shí)文件的字符編碼無(wú)法統(tǒng)一,自己嘗試寫了一些獲取文件字符編碼的工具類贰军,效果不是很理想玻蝌。在網(wǎng)上查閱了很多資料,覺得icu4j比較符合我的業(yè)務(wù)词疼,于是將icu4j引入到項(xiàng)目中使用俯树。
- 引入icu4j依賴
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>70.1</version>
</dependency>
- 編寫工具類
public class CharsetEncodingUtils {
public static String getCharset(InputStream in) throws IOException {
String charset = null;
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(in);
CharsetDetector cd = new CharsetDetector();
cd.setText(bis);
CharsetMatch cm = cd.detect();
if (cm != null) {
charset = cm.getName();
} else {
throw new UnsupportedCharsetException("獲取文件編碼失敗");
}
} catch (IOException e) {
e.printStackTrace();
throw new IOException(e);
}finally {
if (null != bis) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != in) {
in.close();
}
}
return charset;
}
public static void main(String[] args) {
File file = new File("/Users/xxxxx/Documents/批量添加驗(yàn)證樣本模板111/上傳文件樣例-表格 1.txt");
InputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
String charset = getCharset(inputStream);
System.out.println("charset:" + charset);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (null != inputStream) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 測(cè)試case
以下是我做的16個(gè)case,使用16種字符編碼的文件贰盗,通過icu4j來獲取文件的字符編碼许饿,目前測(cè)試來看只要源文件的中文能正常顯示,使用icu4j讀取到的編碼就能正常解析童太,同時(shí)將解析到的內(nèi)容以UTF-8的編碼輸出到新的文件米辐,也沒問題胸完。
輸入文件字符編碼 | ICU4J讀取文件字符編碼 | 輸出UTF-8 | 備注 |
---|---|---|---|
ANSI | GB18030 | 中文轉(zhuǎn)碼通過 | |
BOM UTF-8 | UTF-8 | 中文轉(zhuǎn)碼通過 | |
UTF-16BE | UTF-16BE | 中文轉(zhuǎn)碼通過 | |
UTF-16BE with BOM | UTF-16BE | 中文轉(zhuǎn)碼通過 | |
UTF-16LE | UTF-16LE | 中文轉(zhuǎn)碼通過 | |
UTF-16LE with BOM | UTF-16LE | 中文轉(zhuǎn)碼通過 | |
UTF-8 | UTF-8 | 中文轉(zhuǎn)碼通過 | |
UTF-7 | ISO-8859-1 | 中文轉(zhuǎn)碼未通過 | 源文件中文已經(jīng)亂碼 |
UTF-32 | UTF-32LE | 中文轉(zhuǎn)碼通過 | |
UTF-32BE | UTF-32BE | 中文轉(zhuǎn)碼通過 | |
UTF-32LE | UTF-32LE | 中文轉(zhuǎn)碼通過 | |
GB 18030 | GB18030 | 中文轉(zhuǎn)碼通過 | |
GBK | GB18030 | 中文轉(zhuǎn)碼通過 | |
ISO 2022-CN | ISO-2022-CN | 中文轉(zhuǎn)碼通過 | 源文件中文已經(jīng)亂碼 |
DOS Latin 2 | ISO-8859-1 | 中文轉(zhuǎn)碼未通過 | 源文件中文已經(jīng)亂碼 |
ASCLL | ISO-8859-1 | 中文轉(zhuǎn)碼未通過 | 源文件中文無(wú)法顯示书释,被ASCLL編碼 |