本文节选自洪流学堂公众号技术专栏《大话Unity2018》,未经允许不可转载。

洪流学堂公众号回复专栏,查看更多专栏文章。


洪流学堂,让你快人几步。你好,我是郑洪智。

大智:“昨天我们了解了编码的基本知识,要佩服并感谢一下ISO和Unicode联盟,做了这么伟大的事情将全世界的语言文字统一收录和编码,而这当中包括了那么多我们根本没听说过的奇怪的语言文字。正是因为他们的努力奠定了互联网是一个无国界的世界,每天我们都能通过它获得来自任何地方任何语言的信息。”
小新:“不过这里面的编码的问题何解决呢?”
大智:“今天就给大家带来这个脱坑指南,说说编码方面常遇到的坑。”

乱码是如何出现的?

由于大多数(有些包含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的右下角,可以看到当前文档打开时所用的编码方式。

VS Code打开文档的界面

注意:这里显示的编码方式并不一定是文档真正的编码方式,因为文本文件的编码方式大部分情况是无法检测的。

你会看到上面的文本就出现了很多问号的乱码,这时候可以点击下面UTF-8的部分来用其他编码方式重新打开,如下图所示:

用其他编码方式打开.gif

Visual Studio Code提供了内容猜测的方式来识别文本的编码方式,使用正确的编码方式打开后,你就会发现乱码变为正常的字符了。

那如何将文本转换成UTF8这个最佳的编码方式呢?

1、首先你要确定当前打开的文件中没有显示乱码,如果有乱码尝试用其他的编码方式重新打开
2、选择“通过编码保存”,选择UTF-8即可

用其他编码保存.gif

用代码读文件

之前我们使用了很多次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保准没错,下节课我们再来说说这是个什么东西。”

今日思考题

大智:“试着用C#读取不同编码的文本文件?”
小新:“好嘞!”
大智:“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”


洪流学堂公众号回复专栏,查看更多专栏文章。


《大话Unity2018》,大智带小新学Unity2018的有趣经历,让你学Unity更简单。
所有订阅《大话Unity2018》的用户,可在《大话Unity2019》上线时获得1元换购资格。


[专栏精选]Unity中编码Encoding脱坑指南相关推荐

  1. [专栏精选]Unity中的Git最佳实践

    本文节选自洪流学堂公众号技术专栏<大话Unity2018>,未经允许不可转载. 洪流学堂公众号回复专栏,查看更多专栏文章. 小新:"我昨天尝试了一下使用Git来管理Unity项目 ...

  2. [专栏精选]Unity中动态构建NavMesh

    本文节选自洪流学堂公众号专栏<郑洪智的Unity2018课>,未经允许不可转载. 洪流学堂公众号回复专栏,查看更多专栏文章. 小新:"Unity内置的Navigation系统是不 ...

  3. 技术人综合症脱坑指南

    We_Can_Do_It.jpg 上周遇到一设计师,改了几次设计稿,在电话中尥蹶子不干了.boss在边低声问:"设计师都这样?" 其实心高气傲的岂止是设计师?程序员,工程师,大部分 ...

  4. Redis 脱坑指南

    原文地址:Redis 脱坑指南 博客地址:http://www.extlight.com 一.前言 Redis 是一款 key-value 内存数据库.由于其上手快,执行效率高,拥有多种数据结构,支持 ...

  5. Android 7.0脱坑指南

    本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发. Android适配系列: Android 6.0 的动态权限管理 Android 7.0脱坑指南 Android 8.0适配指北 ...

  6. UI设计中的作品集避坑指南

    在作品集和简历的制作过程中,有很多注意事项值得关注,而这些能够让你的作品集和简历,更上一层楼.今天我总结出来的是设计师简历和作品集中常见的 10 个死穴.在此之前,我因为这些问题而拒绝过很多设计师的申 ...

  7. STM8S系列单片机脱坑指南

    STM8S脱坑指南 你好!这是你第一次使用 STM8S003K3 .如果你想学习如何使用STM8S003K3, 可以速速滚蛋,因为这一点也不好玩.理由如下: 1.参考资料少 2.官方资源少且混乱 3. ...

  8. [专栏精选]Unity动画系统的RootMotion

    洪流学堂,让你快人几步.你好,我是郑洪智. 洪流学堂公众号回复专栏,查看更多专栏文章. "智哥,自从用了混合树来做人物移动,腰不酸腿不疼,思路更清晰了,一口气能写12小时代码!" ...

  9. [专栏精选]Unity动画系统的IK详解

    本文节选自洪流学堂公众号专栏<郑洪智的Unity2018课>,未经允许不可转载. 洪流学堂公众号回复专栏,查看更多专栏文章. "大智,昨天你说要给我讲讲IK,趁现在有空,你给我讲 ...

最新文章

  1. 竞品调研时发现的Android新设计特性
  2. java Socket(二)
  3. 【渝粤教育】国家开放大学2018年春季 3912T★汽车底盘构造与维修 参考试题
  4. epp是什么意思_什么是1K/2K/3K注塑?
  5. 十八般武艺玩转GaussDB(DWS)性能调优:路径干预
  6. android studio8.0,Android Studio错误:(8,0)未找到ID为’android’的插件
  7. python yield原理_从python的yield说起
  8. 中文分词项目(开源/API接口)总结
  9. 命令解析optparse
  10. Linux共享文件夹打不开,Linux 共享文件夹失败
  11. 报表生成器FastReport.Net常见问题解答
  12. sql解决数据库日志文件过大的问题
  13. 装逼软件推荐(持续)
  14. linux 查找目录或文件 (详解)
  15. matlab实现手绘风格(简笔画风格、漫画风格)的曲线绘图
  16. Ubuntu 18.04桌面版卸载不必要的自带软件
  17. 关于SpringBoot如何返回视图
  18. GCC 编译器警告——【-Wunused-variable】【-Wunused-parameter】
  19. 深度学习:神经络的向播和反传播算法导
  20. 日期函数(最近一周/一个月/半年/一年)

热门文章

  1. 12-Mybatis 缓存
  2. 决策树 prepruning_决策树与随机森林
  3. 鸿蒙第三代手机,荣耀Magic 3最新确认,鸿蒙系统+双6400万,最期待的荣耀来了
  4. php 变量代码,php中的可变变量(代码详解)
  5. python3中input输入浅谈_详解Python3中的 input() 函数
  6. UI设计灵感|3D\C4D元素网站,流行最前沿
  7. 设计灵感|什么样的登录页能让用户感到体贴?
  8. 如果你还在寻找完美的海报字体, 你很幸运看这里!
  9. 圣诞节海报设计需要的手写字体素材
  10. php 数据相加,PHP数组合并之array_merge和数组相加