CSV乱码 - UTF-8 Unicode (with BOM)
Unicode
統一碼,也叫萬國碼、單一碼(Unicode)是計算機科學領域里的一項業界標準,包括字符集、編碼方案等。Unicode 是為了解決傳統的字符編碼方案的局限而產生的,它為每種語言中的每個字符設定了統一并且唯一的二進制編碼,以滿足跨語言、跨平臺進行文本轉換、處理的要求。
如果把各種文字編碼形容為各地的方言,那么Unicode就是世界各國合作開發的一種語言。
在這種語言環境下,不會再有語言的編碼沖突,在同屏下,可以顯示任何語言的內容,這就是Unicode的最大好處。 就是將世界上所有的文字用2個字節統一進行編碼。那樣,像這樣統一編碼,2個字節就已經足夠容納世界上所有的語言的大部分文字了。
Unicode的學名是"Universal Multiple-Octet Coded Character Set",通用多八位編碼字符集,簡稱為UCS。
現在用的是UCS-2,即2個字節編碼,而UCS-4是為了防止將來2個字節不夠用才開發的。
BOM
在UCS 編碼中有一個叫做 “Zero Width No-Break Space” ,中文譯名作“零寬無間斷間隔”的字符,它的編碼是 FEFF。而 FEFF 在 UCS 中是不存在的字符,所以不應該出現在實際傳輸中。UCS 規范建議我們在傳輸字節流前,先傳輸字符 “Zero Width No-Break Space”。這樣如果接收者收到 FEFF,就表明這個字節流是 Big-Endian 的;如果收到FFFE,就表明這個字節流是 Little- Endian 的。因此字符 “Zero Width No-Break Space” (“零寬無間斷間隔”)又被稱作 BOM。
UTF-8
UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是針對Unicode的一種可變長度字符編碼。它可以用來表示Unicode標準中的任何字符,而且其編碼中的第一個字節仍與ASCII相容,使得原來處理ASCII字符的軟件無須或只進行少部分修改后,便可繼續使用。因此,它逐漸成為電子郵件、網頁及其他存儲或傳送文字的應用中,優先采用的編碼。
UTF-8 BOM
UTF-8 不需要 BOM 來表明字節順序,但可以用 BOM 來表明編碼方式。字符 “Zero Width No-Break Space” 的 UTF-8 編碼是 EF BB BF。所以如果接收者收到以 EF BB BF 開頭的字節流,就知道這是 UTF-8編碼了。Windows 就是使用 BOM 來標記文本文件的編碼方式的。
CSV文件亂碼問題
類似WINDOWS自帶的記事本等軟件,在保存一個以UTF-8編碼的文件時,會在文件開始的地方插入UTF-8 BOM頭。記事本等編輯器通過它來識別這個文件是否以UTF-8編碼(當然即便沒有UTF-8 BOM頭記事本也能通過其它方式正確識別UTF-8編碼)。
如果一個UTF-8編碼的字符串的開頭處沒有BOM頭又會發生什么?
舉個例子
代碼demo
/*** csv 寫入文件頭** @param pathAndName 文件全路徑名* /Users/yangcheng/Documents/dkangel.csv* @throws IOException IO異常,上層捕獲處理*/private static void addHeadToTmpCsv(String pathAndName) throws IOException {FileOutputStream outputStream = new FileOutputStream(pathAndName, true);try (OutputStreamWriter streamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);BufferedWriter writer = new BufferedWriter(streamWriter)) {writer.write("姓名,年齡,性別");writer.newLine();writer.write("dkangel,25,男");writer.newLine();writer.write("張三,30,男");writer.flush();} finally {outputStream.close();}}public static void main(String[] args) {String path = "/Users/yangcheng/Documents/dkangel.csv";try {addHeadToTmpCsv(path);} catch (IOException e) {e.printStackTrace();}}運行結果
可以通過Java代碼生成csv文件,未指定bom標識,使用excel查看的時候中文亂碼了
文件頭添加bom標識
private static void addHeadToTmpCsv(String pathAndName) throws IOException {FileOutputStream outputStream = new FileOutputStream(pathAndName, true);// 追加BOM標識outputStream.write(0xef);outputStream.write(0xbb);outputStream.write(0xbf);// 或者 writer.write('\uFEFF');......}運行結果
總結
Excel打開沒有BOM頭的csv文件時會出現亂碼問題,添加bom標識后亂碼問題解決
注意
bom標識只用添加一次,那就是文件頭的位置。如果在數據行頭部添加bom標識則單元格數據前會多一個空格出來,可以通過WPS提示看出。
附錄
參考
? unicode:https://baike.baidu.com/item/%E7%BB%9F%E4%B8%80%E7%A0%81/2985798?fromtitle=Unicode&fromid=750500
? bom:https://baike.baidu.com/item/BOM/2790364
? utf-8:https://baike.baidu.com/item/UTF-8/481798
總結
以上是生活随笔為你收集整理的CSV乱码 - UTF-8 Unicode (with BOM)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用transform制作书本翻页效果
- 下一篇: 微信小程序云数据库请求数据并将请求到的数