各类型转字节数组

1
2
3
byte[] bytes = BitConverter.GetBytes(99);// 转换为字节数组

int i = BitConverter.ToInt32(bytes);//转换为int

其他类型同理

编码格式

游戏开发中常用的编码格式:UTF-8

中文相关编码格式:GBK

英文相关编码格式:ASCII


将字符串以制定的编码格式转字节

1
2
3
byte[] bytes2 = Encoding.UTF8.GetBytes("我是紫地丁");

string iAmPditine = Encoding.UTF8.GetString(bytes2);

文件相关操作

文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Lesson2
{
[MenuItem("BinaryLearn/Lesson2")]
private static void Test()
{
if (!File.Exists(Application.dataPath + "/test.pfc")) // 检测文件是否存在
File.Create(Application.dataPath + "/test.pfc");// 创建文件

byte[] bytes = BitConverter.GetBytes(999);
File.WriteAllBytes(Application.dataPath +"/test.pfc",bytes);// 写入文件

string[] strs ={ "hello", "紫地丁","测试" };
File.WriteAllLines(Application.dataPath +"/test2.pfc",strs);// 逐行写入字符串

//将指定字符串写入指定路径
File.WriteAllText(Application.dataPath + "/test3.pfc","测试测试测试\n测试测试测试");

//从文件中读取字节
byte[] bytes2 = File.ReadAllBytes(Application.dataPath + "/test.pfc");
Debug.Log(BitConverter.ToInt32(bytes2));
}
}
1
2
3
4
5
6
7
8
// 删除文件
File.Delete(Application.dataPath + "/test.pfc");

// 复制文件
File.Copy(Application.dataPath + "/oldFile.pfc",Application.dataPath + "/newFile.pfc");

// 替换文件
File.Replace(Application.dataPath + "/newFile.pfc",Application.dataPath + "/targetFile.pfc",Application.dataPath + "/backupFile.pfc");

文件流

创建文件流

方法一

1
FileStream fs = new FileStream(Application.dataPath + "/Lesson3.pfc", FileMode.OpenOrCreate,FileAccess.ReadWrite);

image-20240302183801354

image-20240302183813581

方法二

1
FileStream fs2 = File.Create(Application.dataPath + "Lesson3.pfc");

image-20240302184059522

方法三

1
FileStream fs3 = File.Open(Application.dataPath + "Lesson3.pfc", FileMode.Open);

重要属性和方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FileStream fs = File.Open(Application.dataPath + "Lesson3.pfc", FileMode.OpenOrCreate);

//文件字节数组的长度
Debug.Log(fs.Length);

//是否可写
Debug.Log(fs.CanRead);

//将字节写入文件后一定要执行
fs.Flush();

//关闭流
fs.Close();

//缓存资源销毁回收
fs.Dispose();

读写字节

写入

1
2
3
4
5
6
7
FileStream fs = File.Open(Application.persistentDataPath + "Lesson3.pfc", FileMode.OpenOrCreate,FileAccess.ReadWrite);
byte[] bytes = BitConverter.GetBytes(999);
byte[] bytes2 = Encoding.UTF8.GetBytes("I am Pditine");
fs.Write(bytes,0,4);
fs.Write(bytes2,0,bytes2.Length);
fs.Flush();
fs.Dispose();

读取

1
2
3
4
5
6
7
FileStream fs = File.Open(Application.persistentDataPath + "Lesson3.pfc", FileMode.OpenOrCreate,FileAccess.ReadWrite);
byte[] bytes = new byte[4];
byte[] bytes2 = new byte[16];
Debug.Log(fs.Read(bytes, 0, 4));
Debug.Log(BitConverter.ToInt32(bytes));
Debug.Log(fs.Read(bytes2, 0, 16));
Debug.Log(Encoding.UTF8.GetString(bytes2));

image-20240321232113233

更加安全的使用文件流文件

1
2
3
4
5
6
7
8
9
using (FileStream fs = File.Open(Application.persistentDataPath + "Lesson3.pfc", FileMode.OpenOrCreate,FileAccess.ReadWrite))
{
byte[] bytes = new byte[4];
byte[] bytes2 = new byte[16];
Debug.Log(fs.Read(bytes, 0, 4));
Debug.Log(BitConverter.ToInt32(bytes));
Debug.Log(fs.Read(bytes2, 0, 16));
Debug.Log(Encoding.UTF8.GetString(bytes2));
}

文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
if (Directory.Exists(Application.dataPath + "/数据持久化-二进制"))
Debug.Log("存在文件夹");
DirectoryInfo info = Directory.CreateDirectory(Application.dataPath + "/数据持久化-二进制");

Debug.Log(info.FullName);
Debug.Log(info.Name);

FileInfo[] infos = info.GetFiles();
foreach (var finfo in infos)
{
Debug.Log(finfo.Name);
Debug.Log(finfo.FullName);
Debug.Log(finfo.Length);
Debug.Log(finfo.Extension);

//打开文件流
//finfo.Open();
}

Directory.Delete(Application.dataPath +"/数据持久化-二进制");

//得到指定路径下所有文件夹名
var strs = Directory.GetDirectories(Application.dataPath);
foreach (var str in strs)
{
Debug.Log(str);
}

//得到指定路径下所有文件名
var strs2 = Directory.GetFiles(Application.dataPath);
foreach (var str in strs2)
{
Debug.Log(str);
}

//移动文件夹
Directory.Move(Application.dataPath +"/321",Application.dataPath+"/123");

类对象序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[Serializable]
public struct StructTest
{
public int i;
public string s;

public StructTest(int i, string s)
{
this.i = i;
this.s = s;
}
}

[Serializable]
public class ClassTest
{
public int i;
public string s;

public ClassTest(int i, string s)
{
this.i = i;
this.s = s;
}
}

[Serializable]
public class Person
{
public int age = 1;
public string name = "紫地丁";
public int[] ints = new int[] { 1, 2, 3, 4 };
public List<int> list = new() { 1, 2, 3, 4 };
public Dictionary<int, string> dic = new() { { 1, "123" }, { 2, "123" } };
public StructTest st = new StructTest(2, "321");
public ClassTest ct = new ClassTest(1, "123");
}

方法一 使用内存流得到二进制字节数组

1
2
3
4
5
6
7
8
using MemoryStream ms = new();
BinaryFormatter bf = new();
bf.Serialize(ms,new Person());
byte[] bytes = ms.GetBuffer();

File.WriteAllBytes(Application.dataPath+"/Lesson5.pfc",bytes);

ms.Close();

方法二 使用文件流进行存储

1
2
3
4
5
using FileStream fs = new(Application.dataPath + "/Lesson5_2.pfc", FileMode.OpenOrCreate, FileAccess.Write);
BinaryFormatter bf = new();
bf.Serialize(fs,new Person());
fs.Flush();
fs.Close();

类对象反序列化

反序列化文件中的数据

1
2
3
4
5
using FileStream fs = File.Open(Application.dataPath + "/Lesson5.pfc", FileMode.Open, FileAccess.Read);
BinaryFormatter bf = new();
Person p = bf.Deserialize(fs) as Person;
fs.Close();
Debug.Log(p.name);

反序列化网络传输来的数据

目前没有网络传输,我们还是从文件中读取

1
2
3
4
5
6
7
8
byte[] bytes = File.ReadAllBytes(Application.dataPath + "/Lesson5.pfc");
using (MemoryStream ms = new(bytes))
{
BinaryFormatter bf = new();
Person p = bf.Deserialize(ms) as Person;
ms.Close();
Debug.Log(p.name);
}

类对象的二进制加密

当我们将类对象转换为二进制数据时进行加密,将二进制数据转换为类对象时解密

如果第三方获取到我们的二进制数据,需要得知加密规则和解密密钥才能获取到正确的数据

加密不是100%安全,只能提高破解门槛

常用加密算法

MD5,SHA1,HMAC,AES/DES/3DES

我们一般使用已有的加密算法库以实现数据加密

使用异或加密

一个数异或一个秘钥,即可获得该数的加密数据

加密数据异或这个秘钥,即可获取原数

加密

1
2
3
4
5
6
7
8
9
10
11
12
13
Person p = new Person();
byte key = 238;
using (MemoryStream ms = new())
{
BinaryFormatter bf = new();
bf.Serialize(ms,p);
byte[] bytes = ms.GetBuffer();

for (int i = 0; i < bytes.Length; i++)
{
bytes[i] ^= key;
}
File.WriteAllBytes(Application.dataPath +"/Lesson7.pfc",bytes);

解密

1
2
3
4
5
6
7
8
9
10
11
12
13
byte key = 238;
byte[] bytes = File.ReadAllBytes(Application.dataPath +"/Lesson7.pfc");
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] ^= key;
}

using (MemoryStream ms = new(bytes))
{
BinaryFormatter bf = new();
var p = bf.Deserialize(ms) as Person;
Debug.Log(p.name);
}