Сериализация и десериализация
Введение
В игре мы часто сталкиваемся с такой ситуацией: некоторые данные нужно сохранить в виде файла, чтобы их можно было прочитать и снова использовать во время выполнения. Это включает сериализацию и десериализацию
2. Описание
1. Что такое сериализация/десериализация
- Сериализация: Вообще говоря, это преобразование объекта в двоичную последовательность. Это можно просто понять как преобразование объекта в файл
- Десериализация: Десериализация — это операция, обратная сериализации. Это можно просто понять как процесс преобразования файлов в объекты.
2. Есть несколько способов сериализации
- Общие методы сериализации в играх включают двоичную сериализацию, сериализацию Xml, сериализацию Json и т. д.
- Далее поговорим о конкретных операциях бинарной сериализации и сериализации Xml.
3. Фактическая работа
1. Подготовка к операции
1.1. Определите 2 тестовых класса
Так как необходимо сериализовать объект в xml файл, для удобства тестирования здесь определены два тестовых класса
[System.Serializable]
public class Model
{
//使用[XmlAttribute]特性,生成的xml标签等于该字段名‘val1’
[XmlAttribute]
public int Val1;
//使用[XmlAttribute]特性,并指定生成的xml标签等于‘Val2-alias’,而不是默认的字段名
[XmlAttribute("Val2-alias")]
public int Val2;
//list字段 需要使用[XmlElement]特性,并起别名为ModelItem
[XmlElement("ModelItem")]
public List<ModelItem> itemList;
}
[System.Serializable]
public class ModelItem
{
[XmlAttribute]
public int id;
}
1.2. Построить тестовый класс модели
Затем мы используем метод для создания класса Model и заполнения его тестовыми данными.
/// <summary>
/// 返回一个测试model对象
/// </summary>
/// <returns></returns>
Model BuildModel()
{
Model model = new Model();
model.Val1 = 1;
model.Val2 = 2;
ModelItem modelItem1 = new ModelItem();
modelItem1.id = 123;
ModelItem modelItem2 = new ModelItem();
modelItem2.id = 456;
model.itemList = new List<ModelItem>();
model.itemList.Add(modelItem1);
model.itemList.Add(modelItem2);
return model;
}
2. XML-статьи
2.1, XML-сериализация
/// <summary>
/// 序列化
/// </summary>
void Test_XmlSerializ()
{
//构建model对象
Model model = BuildModel();
//执行序列化到文件的操作
FileStream fs = new FileStream(Application.dataPath+"/Resources/model.xml",FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.ReadWrite);
StreamWriter sw = new StreamWriter(fs,Encoding.UTF8);
XmlSerializer xs = new XmlSerializer(typeof(Model));
xs.Serialize(sw,model);
//关闭文件流
sw.Close();
fs.Close();
}
- Сгенерированный файл выглядит следующим образом, вы можете видеть, что файл был успешно сгенерирован, и данные такие же, как мы определили.
2.2, Десериализация XML
2.2.1, Десериализация XML - через файловый поток
- Существует два метода десериализации Xml. Сначала через файловый поток
/// <summary>
/// 反序列化-通过文件流
/// </summary>
void Test_XmlDeserialize_By_FileStream()
{
//传入文件路径:Application.dataPath+"/Resources/model.xml",构建文件流
FileStream fs = new FileStream(Application.dataPath+"/Resources/model.xml",FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs,Encoding.UTF8);
XmlSerializer xs = new XmlSerializer(typeof(Model));
Model model = xs.Deserialize(sr) as Model;
sr.Close();
fs.Close();
Debug.Log($"model.Val1:{
model.Val1} model.Val2:{
model.Val2} item1Id:{
model.itemList[0].id} item2Id:{
model.itemList[1].id}");
}
//打印如下
//model.Val1:1 model.Val2:2 item1Id:123 item2Id:456
2.2.1, Десериализация XML - через строковый литерал
- десериализовать по строке
- Иногда наши Xml-файлы помещаются в каталог Resources, например, файлы, сгенерированные выше, находятся в этом каталоге. После того, как файл в каталоге Resources фактически упакован, файл нельзя получить с помощью чистого пути, поэтому нет возможности десериализовать его с помощью файлового потока. Как читать в этом случае, вы можете использовать Resources.Load() для чтения текста строки, а затем использовать метод десериализации текста строки. код показывает, как показано ниже
/// <summary>
/// 反序列化-通过字符串文本
/// </summary>
void Test_XmlDeserialize_By_String()
{
//读取Resources/model.xml文件
TextAsset textAsset = Resources.Load<TextAsset>("model");
StringReader sr = new StringReader(textAsset.text);
XmlSerializer xs = new XmlSerializer(typeof(Model));
Model model = xs.Deserialize(sr) as Model;
Debug.Log($"model.Val1:{
model.Val1} model.Val2:{
model.Val2} item1Id:{
model.itemList[0].id} item2Id:{
model.itemList[1].id}");
}
//打印如下
//model.Val1:1 model.Val2:2 item1Id:123 item2Id:456
3. Бинарный
3.1, бинарная сериализация
void Test_ByteSerialize()
{
//构建model类
Model model = BuildModel();
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(Application.dataPath+"/Resources/model.byte",FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.ReadWrite);
bf.Serialize(fs,model);
fs.Close();
}
- Снимок экрана
Вы можете видеть, что файл model.byte был успешно сгенерирован.
3.2 Двоичная десериализация
void Test_ByteDeserialize()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(Application.dataPath+"/Resources/model.byte",FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.ReadWrite);
Model model = bf.Deserialize(fs) as Model;
Debug.Log($"model.Val1:{
model.Val1} model.Val2:{
model.Val2} item1Id:{
model.itemList[0].id} item2Id:{
model.itemList[1].id}");
}
//打印如下
//model.Val1:1 model.Val2:2 item1Id:123 item2Id:456