问题:
加入的unity学习群里,出现群友遇到一个问题:读取txt文件之后,分解出的第一个字符应该是1,但是把它转换成int的时候,一直报错,错误为System.FormatException:“Input string was not in a correct format.”
读取和分解代码如下:
static void Main(string[] args)
{
string config = ReadTxt();
string[] value = config.Split('~');
string cc = value[0].Split('_')[0];
int d = int.Parse(cc);
Console.WriteLine(d);
Console.ReadLine();
}
static string ReadTxt()
{
//文件路径
string filePath = @"F:\config.txt";
string text1 = "";
try
{
if (File.Exists(filePath))
{
text1 = File.ReadAllText(filePath);
byte[] mybyte = Encoding.UTF8.GetBytes(text1);
text1 = Encoding.UTF8.GetString(mybyte);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return text1;
}
txt文本内容为:
1_Name=云冈石窟~2_Name=悬空寺
在经过群友的一番讨论下,先是一步步确认字符串分解打印是否有问题。然后还引申出字符串string按索引取出的值是char类型,讨论下打印char类型其实打印出来的是ascll码。
其实对代码进行分析之后,发现代码并没有发现问题。然后考虑读取的文档内容,因为在代码里面打印出来的内容都是正常的。后面就检查了txt文档的编码格式。
而发现群友的电脑,在保持txt文档的时候,自动把编码变成了带有BOM的UTF-8编码。把它替换成不带BOM的,就完美解决问题。
什么是带有BOM的UTF-8编码格式?
BOM(byte-order mark),即字节顺序标记,它是插入到以UTF-8、UTF16或UTF-32编码Unicode文件开头的特殊标记,用来识别Unicode文件的编码类型。对于UTF-8来说,BOM并不是必须的,因为BOM是用来标记多字节编码文件的编码类型和字节顺序(big-endian或little- endian)。而UTF8中,每个字符的编码有多少位是通过第一个字节来表述的,而且没有big-endian和little-endian的区分,见后述。
BOMs 文件头:
00 00 FE FF = UTF-32, big-endian
FF FE 00 00 = UTF-32, little-endian
EF BB BF = UTF-8,
FE FF = UTF-16, big-endian
FF FE = UTF-16, little-endian
还有一个要注意的是:UTF-8 的网页代码不应使用 BOM,否则常常会出错:
在网页上使用BOM是个错误。BOM设计出来不是用来支持HTML和XML的。要识别文本编码,HTML有charset属性,XML有encoding属性,没必要拉BOM撑场面。虽然理论上BOM可以用来识别UTF-16编码的HTML页面,但实际工程上很少有人这么干。毕竟UTF-16这种编码连ASCII都双字节,实在不适用于做网页。
Windows使用BOM的历史原因:
通常BOM是用来标示Unicode纯文本字节流的,用来提供一种方便的方法让文本处理程序识别读入的.txt文件是哪个Unicode编码(UTF-8,UTF-16BE,UTF-16LE)。Windows相对对BOM处理比较好,是因为Windows把Unicode识别代码集成进了API里,主要是CreateFile()。打开文本文件时它会自动识别并剔除BOM。Windows用这个有历史原因,因为它最初脱胎于多代码页的环境。而引入Unicode时Windows的设计者又希望能在用户不注意的情况下同时兼容Unicode和非Unicode(Multiple byte)文本文件,就只能借助这种小trick了。
上面这段是查询到的资料。
而群友的电脑无法把txt文件保存成为不带BOM的UTF-8格式的文本,ctrl+S也会直接修改原先已经是UTF-8格式的文本,只能建议他下载notepad++或者其他编辑文本的软件了!