字符串类型以及非字符串类型转换为字节数组分别使用BitConverter类和Encoding类进行转换

1
2
byte[]  bytes = BitConverter.GetBytes(1);  //非字符串
byte[] bytes1 = Encoding.UTF8.GetBytes("11111"); //字符串

字节数组转为其他类型的数据

1
2
int i = BitConverter.ToInt32(bytes,0); 
string str = Encoding.UTF8.GetString(bytes1);//这个字符数组全是字符串

对于如何将类序列化,不能直接使用C#中的BinaryFormatter进行2进制的序列化,因为是C#语言的规则与其他语言的兼容性不好,如果使用它那么其他语言开发的服务器无法进行反序列化,使用需要自定义处理类对

文件写入以及创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FileStream fs = File.Create(path);//创建文件
------------------------------------------------------ //写入文件
byte[] buffer = Encoding.UTF8.GetBytes("11111");
File.WriteAllBytes(Application.dataPath + "/UnityTeach/Lessons.txt", buffer);

string[] strs = new string(){"1","2"};
File.WriteAllLines(Application.dataPath + "/UnityTeach/Lessons.txt",strs);

File.WriteAllText(FilePath,contend);

---------------------------------------------------//读取文件
buffer = File.ReadAllBytes(FilePath);
strs = File.ReadAllLines(FilePath);

---------------------------------------------------//删除文件
File.Delete(path);

Unity 特殊路径

路径类型 描述
Application.dataPath Assets/ 文件夹路径(编辑器下可写,打包后只读)
Application.persistentDataPath 持久化数据路径(所有平台可写,如 C:/Users/.../AppData/Local/ 等)
Application.streamingAssetsPath 只读路径,存放需随包发布的文件(如初始配置)

C#类的序列化和反序列化

序列化

如果使用C#自带的序列化的方法时,需要在类前面加上[System.Serializable]特性,表示该类可以被序列化。

方法一:使用内存流得到2进制字节数组,主要用于得到字节数组,可以用于网络传输。

  • 内存流对象:类名为MemoryStream,命名空间System.IO
  • 2进制格式化对象:类名为BinaryFormatter,命名空间为System.Runtime.Serializable.Formatters.Binary
1
2
3
4
5
6
7
8
9
10
11
using (MemoryStream ms = new MemoryStream()){
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms,p);
// 获取内存流中的字节数组
byte[] data = ms.GetBuffer();

// 将字节数组写入文件
File.WriteAllBytes(Application.dataPath + "/person.dat", data);
// 关闭内存流 (using 语句会自动调用)
ms.Close();
}

方法二:使用文件流进行存储,主要用于存储到文件中

  • 文件流对象:类名为FileStream
1
2
3
4
5
6
using(FileStream fs = new FileStream(Application.dataPath + "/person.dat",FileMode.OpenOrCreate,FileAccess.Write )){
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs,p);
fs.Flush();
fs.Close();
}

反序列化

1.反序列文件中的数据,使用文件流进行反序列化。

首先打开文件,使用2进制格式化类。

1
2
3
4
5
6
using (FileStream fs = FileStream.Open(Application.dataPath + "/person.dat",FileMode.Open,FileAccess.Read)){
BinaryFormatter bf = new BinaryFormatter();
//bf.Deserialize(fs)是一个Object对象 ,所以需要进行数据转换
Person p = bf.Deserialize(fs) as Person;
fs.Close();
}

2.反序列化网络传输过来的2进制数据

  • 使用内存流类:类名为MemoryStream,命名空间System.IO
1
2
3
4
5
using (MemoryStream ms = new MemoryStream(bytes)){
BinaryFormatter bf = new BinaryFormatter();
Person p = bf.Deserialize(ms) as Person;
bf.Close();
}

C#类对象的2进制数据加密

使用场景:

  • 类对象转化为2进制对象时进行加密
  • 2进制对象转为类对象是进行解密

常用的加密算法:

  • MDS算法
  • SHA1算法
  • HMAC算法
  • AES/DES/3DES算法

简单的异或加密算法

异或运算的特性:(相同为0,不同为1(转换为2进制))

  • 如果 A XOR B = C
  • 那么 C XOR B = A
  • 即:`(data ^ key) ^ key = data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Person p = new Person();
public byte Key = 11;
using (MemoryStream ms = new MemoryStream()){
BinaryFormatter bf = new BinaryFormatter();
bf.serialize(ms,p);
byte[] bytes = ms.GetBuffer();
//异或加密
for(int i = 0;i<bytes.Length;i++){
bytes[i]^=Key;
}
File.WriteAllBytes(Application.dataPath + "/Person.dat",bytes);
ms.Close();
}
byte[] bytes2 = File.ReadAllBytes(Application.dataPath + "/Person.dat");
for(int i = 0;i<bytes2.Length;i++){
bytes2[]^ =Key;
}
using (MemoryStream ms = new MemoryStream(bytes)){
BinaryFormatter bf = new BinaryFormatter();
Person p = bf.Deserialize(ms) as Person;
bf.Close();
}

数据的保存和加载的管理器

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
39
40
41
42
43
44
45
46
47
48
49
50
51
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

public class SaveAndLoadBinary : MonoBehaviour
{
private static SaveAndLoadBinary instance;
public static SaveAndLoadBinary Instance{
get{
return instance;
}
}
public static string Save_Path = Application.persistentDataPath + "/Data/";

/// <summary>
/// 以二进制的方式保存数据
/// </summary>
/// <param name="obj"></param>
/// <param name="FileName"></param>
public void Save(Object obj,string FileName){
// 如果文件夹不存在,则创建文件夹
if(!Directory.Exists(Save_Path)){
Directory.CreateDirectory(Save_Path);
}
using (FileStream fs =new FileStream(Save_Path + FileName,FileMode.OpenOrCreate,FileAccess.Write)){
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs,obj);
fs.Flush();
fs.Close();
}
}
/// <summary>
/// 以二进制的方式加载数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="FileName"></param>
/// <returns></returns>
public T Load<T>(string FileName)where T:class{
// 如果文件不存在,则返回默认值
if(!File.Exists(Save_Path + FileName)){
return default(T);
}
T obj;
using (FileStream fs =new FileStream(Save_Path + FileName,FileMode.Open,FileAccess.Read)){
BinaryFormatter bf = new BinaryFormatter();
obj = (T)bf.Deserialize(fs);
fs.Close();
}
return obj;
}
}

Unity添加菜单栏选项

通过Unity提供的MenuItem特性在菜单栏生成选项。

规则如下:

  • 规则一:必须是静态方法static
  • 规则二:菜单栏按钮必须有2级标题
  • 规则三:这个特性可以用在任意的类当中
1
2
3
4
[MenuItem("GameTool/Test")]
private static void Test(){

}