Unity中編碼Encoding問題

 

轉載:https://zhuanlan.zhihu.com/p/62374050

我在項目中遇到的問題主要是塊中的問題,編輯器界面解析正常,打包出來還是亂碼。

 

亂碼是如何出現的?
由於大多數(有些包含BOM)文本中並沒有包含特定信息,指示文本使用了什麼編碼方式,當文本在文件或者網絡中交換時,可能會導致保存文本的編碼和打開文本的編碼不一致。這時候文本解析出來的字符就可能不一致,甚至有些根本就沒有對應的字符,就會顯示爲亂碼。
BOM
前兩天我們說到使用UTF8 without BOM的編碼方式是最佳的選擇。那這個BOM是個什麼東西呢?
BOM(Byte-Order Mark,字節序標記)是Unicode碼點U+FEFF。它被定義來放在一個UTF-16文件的開頭,如果字節序列是FEFF那麼這個文件就是大端序,如果字節序列FFFE那麼這個文件就是小端序。
UTF-8本身是沒有字節序的問題的(因爲它是以單個字節爲最小單位),但是Windows裏面很多編輯器(比如記事本)會多此一舉的在UTF-8文件開頭加入EF BB FF也就是U+FEFF的UTF-8編碼。
如果你的文本文件裏面有一個這東西你就倒了大黴了,可能會:

  • 文件用一些編輯器打開出現亂碼。
  • 使用代碼讀取文件會出錯。

建議在Windows上做開發的同學,如果遇到了編碼問題,一定要選擇“使用UTF-8無BOM格式”保存。
Unity中的代碼目前使用的默認編碼方式是UTF8。

C#中的編碼處理
在開發中我們可以控制編碼的格式,但是很多情況下我們還是要處理非UTF8編碼的文本,這時候怎麼做呢?下面我們學習一下在C#中如何和“編碼”友好相處。
讀文件
之前我們在讀取文件時,都沒有關注過編碼這個問題,因爲我們之前文件保存的編碼方式是UTF8。
讀文件的時候想把文件中的正確內容讀取出來有兩個關鍵的地方:

  • 文件的編碼方式是什麼
  • 讀取的時候編碼方式是什麼

文件的編碼方式
文件的編碼方式是多種多樣的,昨天我們提到的那些編碼方式都可以作爲文件的編碼。文件的編碼如何查看以及修改呢呢?
在這裏推薦Visual Studio Code這個編輯器。在Visual Studio Code的右下角,可以看到當前文檔打開時所用的編碼方式。

注意:這裏顯示的編碼方式並不一定是文檔真正的編碼方式,因爲文本文件的編碼方式大部分情況是無法檢測的。
你會看到上面的文本就出現了很多問號的亂碼,這時候可以點擊下面UTF-8的部分來用其他編碼方式重新打開。

Visual Studio Code提供了內容猜測的方式來識別文本的編碼方式,使用正確的編碼方式打開後,你就會發現亂碼變爲正常的字符了。
那如何將文本轉換成UTF8這個最佳的編碼方式呢?
1、首先你要確定當前打開的文件中沒有顯示亂碼,如果有亂碼嘗試用其他的編碼方式重新打開
2、選擇“通過編碼保存”,選擇UTF-8即可

用代碼讀文件
之前我們使用了很多次File.ReadAllText,其實它還有第二個參數:
public static string ReadAllText(string path, Encoding encoding);
如果不傳入這個參數,會使用默認的編碼方式:
Debug.Log(System.Text.Encoding.Default); // 你會看到這個輸出是UTF8
那如果我們的文本文件是GB2312的編碼方式,讀出來的文件會怎樣呢?
using System.Collections;using System.Collections.Generic;using System.IO;using System.Text;using UnityEngine;public class FileWithEncoding : MonoBehaviour{ void Start() { var path = Path.Combine(Application.streamingAssetsPath, "data.txt"); Debug.Log(Encoding.Default); var text = File.ReadAllText(path, Encoding.Default); Debug.Log(text); }}

 

改成下面這一行以後,你就能獲取到正確的編碼文本了!
var text = File.ReadAllText(path, Encoding.GetEncoding("GB2312"));


Unity發佈後讀取亂碼
到這還沒完,如果你將上面的簡單的程序發佈出來,你會發現又不行了!
這時候是咋回事呢?我將思路提供給你。
1、先想辦法找到線索,那就是Log文件。發佈出來的Exe的log文件的位置是:
macOS ~/Library/Logs/Unity/Player.logWindows C:\Users\<username>\AppData\LocalLow\CompanyName\ProductName\output_log.txt
對於我就是:
C:\Users\32954\AppData\LocalLow\DefaultCompany\198Encoding
2、找到log文件後打開,你會發現這麼一句話
NotSupportedException: Encoding 936 data could not be found. Make sure you have correct international codeset assembly installed and enabled.
3、這時候你就可以拿這句話去google了,你肯定能找到答案
我也把答案附上吧:
原因是Unity在發佈時並沒有包含這些字符集,需要手動加進去,方法是:
1、找到Unity安裝目錄
2018.3.0f2\Editor\Data\Mono\lib\mono\2.0
將裏面的I18N.dllI18N.CJK.dll複製到工程中

2、重新發布即可
BOM如何處理
其實使用C#的File類時,你不需要對BOM進行特殊處理,因爲C#自動幫你處理了BOM,但是如果是通過網絡傳輸或者其他情況,BOM可能會害的你很慘。這個我們後面學到使用WebRequest時再詳說。
總結
大智:“說了這麼多,相信你已經對編碼有一定的瞭解了。那我們到底應該用什麼編碼呢?用UTF8 without BOM保準沒錯,下節課我們再來說說這是個什麼東西。”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章