Unity教程之-字符编码与二进制文件的读写

 

字符编码的重要性:

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。

因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

基础知识:

1字节=8位,可以表示256个字符,从8个0到8个1

c#数据类型占用的字节数:

bool -> System.Boolean (布尔型,其值为 true 或者 false)

byte -> System.Byte (字节型,占 1 字节,表示 8 位正整数,范围 0 ~ 255)

sbyte -> System.SByte (带符号字节型,占 1 字节,表示 8 位整数,范围 -128 ~ 127)

char -> System.Char (字符型,占2字节,表示 1 个 Unicode 字符)

short -> System.Int16 (短整型,占 2 字节,表示 16 位整数,范围 -32,768 ~ 32,767)

ushort -> System.UInt16 (无符号短整型,占 2 字节,表示 16 位正整数,范围 0 ~ 65,535)

uint -> System.UInt32 (无符号整型,占 4 字节,表示 32 位正整数,范围 0 ~ 4,294,967,295)

int -> System.Int32 (整型,占 4 字节,表示 32 位整数,范围 -2,147,483,648 到 2,147,483,647)

float -> System.Single (单精度浮点型,占 4 个字节)

ulong -> System.UInt64 (无符号长整型,占 8 字节,表示 64 位正整数,范围 0 ~ 大约 10 的 20 次方)

long -> System.Int64 (长整型,占 8 字节,表示 64 位整数,范围大约 -(10 的 19) 次方 到 10 的 19 次方)

double -> System.Double (双精度浮点型,占8 个字节)

常见字符编码:

1. ASCII码

ASCII码一共规定了128个字符的编码,只占用了一个字节的后面7位,最前面的1位统一规定为0。

缺点:英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。

2.Unicode(相当于UTF-16)

Unicode是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,可以解决乱码问题。一个Unicode字符由两个字节组成。

缺点:Unicode固然统一了编码方式,但是它的效率不高,比如UCS-4(Unicode的标准之一)规定用4个字节存储一个符号,那么每个英文字母前都必然有三个字节是0,这对存储和传输来说都很耗资源。

3.UTF-8

为了提高Unicode的编码效率,于是就出现了UTF-8编码。UTF-8可以根据不同的符号自动选择编码的长短。比如英文字母可以只用1个字节就够了。

UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。

4.GBK

GBK采用双字节表示,解决汉字编码的问题。

c#中二进制文件的读写:

BinaryWriter类:https://msdn.microsoft.com/zh-cn/library/system.io.binarywriter.aspx

BinaryReader类:https://msdn.microsoft.com/zh-cn/library/system.io.binaryreader.aspx

Array.Copy:从指定的源索引开始,复制 Array 中的一系列元素,将它们粘贴到另一Array 中(从指定的目标索引开始)。


using UnityEngine;
using System.Collections;
using System.IO;
using System.Text;
using UnityEditor;

public class TestByte : MonoBehaviour {

void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1)) WriteByte();
if (Input.GetKeyDown(KeyCode.Alpha2)) ReadByte();
}

void WriteByte()
{
string path = Application.dataPath + @"/binary.txt";

if (File.Exists(path))
File.Delete(path);
FileStream fs = new FileStream(path,FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);

bw.Write("宏哥");
bw.Write((short)1995);
bw.Write((int)2015);
bw.Write((float)530);
bw.Write(true);

bw.Close();
fs.Close();

AssetDatabase.Refresh();
}

void ReadByte()
{
string path = Application.dataPath + @"/binary.txt";

FileStream fs = new FileStream(path, FileMode.Open);
BinaryReader bw = new BinaryReader(fs);

print(bw.ReadString());
print(bw.ReadInt16());
print(bw.ReadInt32());
print(bw.ReadSingle());
print(bw.ReadBoolean());

bw.Close();
fs.Close();
}
}

二进制文件:

输出: