关于Unity读取和写入
01.序列化与反序列化
序列化
- 在需要在unity中进行序列化时,如果是类序列化,则继承的类也需要序列化
- 所以在里面要序列化的情况下,不要继承 MonoBehaviour
- 序列化特性是一种快捷的方式,如果不加序列化特性的话,需要自己将这个序列化进行编写。
序列化过程
不管是 XML 还是 Json 还是二进制文件。这些都是需要先对需要转换的内容进行储存。
- 先创建一个只有属性和字段的类,用来显示需要保存的框架
- 然后实例化这个类,用来写入需要保存的数据
- 然后将这个实例化的类,赋值给 XML 或 Json 或 二进制文件。
02.二进制存储
二进制存储与读取
BinaryFormatter 类
这个类是以二进制格式序列化和反序列化对象或连接对象的整个图形。
需要引入命名空间
System.Runtime.Serialization.Formatters.Binary
1. 保存
-
引入需要保存的类对象
//下面是序列化的过程(将Save对象转换为字节流) //创建Save对象,并保存当前游戏状态 Save save = SaveButtonInfo();
-
创建一个 BinaryFormatter 类
- 二进制要用这个类
//创建一个二进制格式化程序 BinaryFormatter bf = new BinaryFormatter();
-
创建一个二进制文件流来保存数据(FileStream)
//创建一个文件流来保存 //Application.dataPath(包含游戏数据文件夹的路径(只读)) FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/byBin.txt");
-
创建序列化
//用二进制格式化程序的序列化方法来序列化Save对象。 //参数:创建的文件流和需要序列化的对象。 bf.Serialize(fileStream, save);
-
关闭流
//关闭流 fileStream.Close();
2. 加载
-
创建一个
//反序列化过程 //创建一个二进制格式化程序 BinaryFormatter bf = new BinaryFormatter();
-
打开一个有储存内容的文件流
//打开一个文件流 FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" + "/byBin.txt", FileMode.Open);
-
调用反序列化方法,用已有类进行接收
//调用格式化程序的反序列化方法,将文件流转换为一个 Save 对象 //这个打开是 Object 类型,要强制打开 Object 类型 Save save = (Save)bf.Deserialize(fileStream);
-
关闭文件流
//关闭文件流 fileStream.Close();
-
调用需要使用读取数据完成后的方法
//调用方法 LoadButtonInfo(save);
03.XML存储
XML存储与读取
1.保存
-
获得需要保存的类(同时获取本地文件地址)
Save save = SaveButtonInfo(); //Application.dataPath 是Unity获取本地文件的地址 string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
-
创建一个 XML 文档类型的类
//创建 XML 文档 XmlDocument xmlDoc = new XmlDocument();
-
创建第一个根节点,即第一层节点
//创建跟节点,即最上层的节点 XmlElement root = xmlDoc.CreateElement("save");
-
设置该节点的属性
//设置该节点的一个属性 root.SetAttribute("name", "saveFile1");
-
声明新的节点
//声明target、SaveTagetNumber、SaveMonsterNumber节点 XmlElement target; XmlElement SaveTagetNumber; XmlElement SaveMonsterNumber;
-
在创建的新的节点中加入数据,并创建层级关系
//遍历save中存储的数据,将数据转换成XML格式 //save.SaveTagetNumber是save中该字段列表中拥有的数据数量 for (int i = 0; i < save.SaveTagetNumber.Count; i++) { //创建节点名称(实例) target = xmlDoc.CreateElement("target"); SaveTagetNumber = xmlDoc.CreateElement("SaveTagetNumber"); //向需要创建节点名称中添加数据 SaveTagetNumber.InnerText = save.SaveTagetNumber[i].ToString(); SaveMonsterNumber = xmlDoc.CreateElement("SaveMonsterNumber"); SaveMonsterNumber.InnerText = save.SaveMonsterNumber[i].ToString(); //设置节点间的层级关系 root -- target -- (SaveTagetNumber,SaveMonsterNumber) root.AppendChild(target); target.AppendChild(SaveTagetNumber); target.AppendChild(SaveMonsterNumber); }
-
创建新的节点并加入层级关系
//设置得分的节点(值和层级关系) XmlElement saveScore = xmlDoc.CreateElement("saveScore"); //向需要创建节点名称中添加数据 saveScore.InnerText = save.saveScore.ToString(); root.AppendChild(saveScore); //设置得分的节点(值和层级关系) XmlElement saveScore = xmlDoc.CreateElement("saveScore"); //向需要创建节点名称中添加数据 saveScore.InnerText = save.saveScore.ToString(); root.AppendChild(saveScore);
-
将根节点放入到Xml文档中
xmlDoc.AppendChild(root);
-
将此 XML 文件存入本地文件当中
//filePath 这个是本地文件地址 xmlDoc.Save(filePath);
2.读取(在读取数据前需要判断数据是否存在)
-
创建一个需要接收数据的类的实例
Save save = new Save(); string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
-
将 XML 类型的文档加载
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(filePath);
-
通过节点名称来获取节点数组
//通过节点名称来获取元素,结果为XmlNodeList类型 XmlNodeList targets = xmlDoc.GetElementsByTagName("target");
-
遍历出每个 target 节点下面的所有子节点(并获取它的值)
//遍历所有的 target 节点,并获得子节点和子节点的InnerText; if (targets.Count != 0) { foreach (XmlNode target in targets) { //获取位置为0的子节点 XmlNode SaveTagetNumber = target.ChildNodes[0]; //获取子节点的值 int SaveTagetNumberIndex = Int32.Parse(SaveTagetNumber.InnerText); //将取得的值存储到 save 中 save.SaveTagetNumber.Add(SaveTagetNumberIndex); //获取位置为1的子节点 XmlNode SaveMonsterNumber = target.ChildNodes[1]; int SaveMonsterNumberIndex = Int32.Parse(SaveMonsterNumber.InnerText); //获取子节点的值 save.SaveMonsterNumber.Add(SaveMonsterNumberIndex); } }
-
通过节点名称获取节点数组
XmlNodeList shoot = xmlDoc.GetElementsByTagName("saveShoot"); int shootCount = Int32.Parse(shoot[0].InnerText); save.saveShoot = shootCount; XmlNodeList score = xmlDoc.GetElementsByTagName("saveScore"); int scoreCount = Int32.Parse(score[0].InnerText); save.saveScore = scoreCount;
-
将这个保存好数据的实例传入到需要这个实例的方法
LoadButtonInfo(save);
04.Json存储
Json存储与读取
1.保存
-
打开需要保存的类
//打开需要保存的类 Save save = SaveButtonInfo(); string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
-
将需要保存的类转化为 Json 类
//将需要保存的类转化为json数据 string jsonStr = JsonMapper.ToJson(save);
-
创建一个流文件用来进行写入 Json 文本
//创建一个流文件用来写入(这个流文件为json文字格式的流文件) StreamWriter jsonWriter = new StreamWriter(filePath); //将转换好的json类型的文本写入流文件。 jsonWriter.Write(jsonStr);
-
关闭流
//关闭流 jsonWriter.Close();
2.加载(加载前先判断文件是否存在)
-
创建一个流文件形式来加载已经有 Json 格式数据的文件
//创建一个流来读取文件 string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json"; StreamReader jsonReader = new StreamReader(filePath);
-
一直读取到结尾
//这个是读取到结尾(读取出来的是json类型的格式) string jsonStr = jsonReader.ReadToEnd();
-
关闭流
//关闭流 jsonReader.Close();
-
用 Json 里的方法将 Json 格式的文本读取,赋值给 Save 类
//用Json里的方法将Json格式的文本读取,赋值给Save类 Save save = JsonMapper.ToObject<Save>(jsonStr);
-
将这个保存好数据的实例传入到需要这个实例的方法
//调用方法 LoadButtonInfo(save);