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保准没错,下节课我们再来说说这是个什么东西。”

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值