前言
最近需要实现一个序列化反序列化工具,由于数据不是很复杂,所以自己实现一个简单的工具
设计
- 首先得有一个数据类,比如PlayerData
- PlayerData里面存储具体需要存储的数据类,比如需要存储Player身上一些碰撞体的数据,刚体的数据等等。
- 数据有了之后,我们就需要序列化工具了,比如叫做DataSerializeHelper,它负责序列化传过来的数据
- 我们还需要一个写入文件的类,比如叫做DataFileUtility,它负责把传过来的字符串写入到指定文件中
代码
public class PlayerData
{
public string[] rb_data {
get; set; }//比如[mass, drag] (按照自己的规则就好了)
private DataSerializeHelper serialize_helper;
private const string rb_data_key = "rb_data";
public PlayerData()
{
serialize_helper = new DataSerializeHelper();
}
public void Serialize(string file_path)
{
File.WriteAllText(file_path, "");//先清空
string rb_data_content = serialize_helper.Serialize(rb_data);
DataFileUtility.Append(file_path, rb_data_content, rb_data_key);
}
public void Deserialize(string file_content)
{
serialize_helper.DeSerialize(file_content);
rb_data = serialize_helper.GetListByKey(rb_data_key);
}
}
public class DataSerializeHelper
{
private string SPLIT_SIGN = ",";
private Dictionary<string, string[]> kv_dict = new Dictionary<string, string[]>();
//需要在调用DeSerialize之后才有用
public string[] GetListByKey(string key)
{
return kv_dict.ContainsKey(key) ? kv_dict[key] : new string[0];
}
public string Serialize(string[] list)
{
StringBuilder sb = new StringBuilder();
foreach (string data in list)
{
sb.Append(data).Append(SPLIT_SIGN);
}
if (sb.Length > 0)
{
sb.Remove(sb.Length - 1, 1);//去掉最后一个SPLIT_SIGN
}
return sb.ToString();
}
public void DeSerialize(string content)
{
if (content.Equals("")) return;
//由于content直接从文件读取,并且文件最后一行是空的,所以得删除最后一个元素
DeSerialize((content.Remove(content.Length - 1)).Split("\n"));
}
public void DeSerialize(string[] contents)
{
for (int i = 0, step = 2; i < contents.Length; i += step)
{
string key = contents[i];
string[] value = contents[i + 1].Split(SPLIT_SIGN);
//如果key为空并且内容也为空,则不加入字典
if (!key.Equals("") && !contents[i + 1].Equals(""))
{
kv_dict.Add(key, value);
}
}
}
}
public static class DataFileUtility
{
public static void Write(string file_path, string content, string key)
{
string res_content = key + "\n" + content + '\n';
File.WriteAllText(file_path, res_content);
}
public static void Append(string file_path, string content, string key)
{
if (!File.Exists(file_path))
{
Write(file_path, content, key);
}
else
{
string res_content = key + "\n" + content + '\n';
File.AppendAllText(file_path, res_content);
}
}
public static string[] ReadAllLines(string file_path)
{
return File.Exists(file_path) ? File.ReadAllLines(file_path) : null;
}
public static string ReadAllText(string file_path)
{
return File.Exists(file_path) ? File.ReadAllText(file_path) : null;
}
}
public void Serialize()
{
PlayerData data = new PlayerData();
data.rb_data = new string[] {
10, 10};//mass, drag
string file_path = "player_data.txt";
data.Serialize(data);
}
public void Deserialize()
{
PlayerData data = new PlayerData();
string file_path = "player_data.txt";
data.Deserialize(data);
print(data.rb_data);
}
总结
如果想加数据,直接在数据类里面加一个成员变量和对应的key值就好了,不需要修改内部的代码
只是需要在外部拿取string数组里面的数据,然后根据自己的规则,做自己的事就好了(比如赋值等等)。
预告
下篇文章将讨论下我在Unity中具体使用怎么使用JsonUtility存储数据以及踩到的一些坑