国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity XML3——XML序列化

這篇具有很好參考價值的文章主要介紹了Unity XML3——XML序列化。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、XML 序列化

? 序列化:把對象轉化為可傳輸的字節(jié)序列過程稱為序列化,就是把想要存儲的內容轉換為字節(jié)序列用于存儲或傳遞

??反序列化:把字節(jié)序列還原為對象的過程稱為反序列化,就是把存儲或收到的字節(jié)序列信息解析讀取出來使用

(一)XML 序列化

1.準備數據結構

public class Lesson1Test
{
    public    int          testPublic    = 10;
    private   int          testPrivate   = 11;
    protected int          testProtected = 12;
    internal  int          testInternal  = 13;
    public    string       testPUblicStr = "123";
    public    int          testPro { get; set; }
    public    Lesson1Test2 testClass = new Lesson1Test2();
    public    int[]        arrayInt  = new int[3] { 5, 6, 7 };
    
    public    List<int> listInt = new List<int>() { 1, 2, 3, 4 };
    
    public    List<Lesson1Test2> listItem = new List<Lesson1Test2>() { new Lesson1Test2(), new Lesson1Test2() };

    // 不支持字典
    // public Dictionary<int, string> testDic = new Dictionary<int, string>() { { 1, "123" } };
}

public class Lesson1Test2
{
    public int test1 = 1;
    public float test2 = 1.1f;
    public bool test3 = true;
}

Lesson1Test lt = new Lesson1Test();

2.進行序列化

XmlSerializer:用于序列化對象為 xml 的關鍵類

StreamWriter:用于存儲文件

using:用于方便流對象釋放和銷毀

using System.Xml.Serialization;

// 第一步:確定存儲路徑
string path = Application.persistentDataPath + "/Lesson1Test.xml";

// 第二步:結合 using知識點 和 StreamWriter這個流對象 來寫入文件
// 括號內的代碼:寫入一個文件流 如果有該文件 直接打開并修改 如果沒有該文件 直接新建一個文件
// using 的新用法 括號當中包裹的聲明的對象 會在 大括號語句塊結束后 自動釋放掉 
// 當語句塊結束 會自動幫助我們調用 對象的 Dispose這個方法 讓其進行銷毀
// using一般都是配合 內存占用比較大 或者 有讀寫操作時  進行使用的 
using (StreamWriter stream = new StreamWriter(path)) {
    // 第三步:進行xml文件序列化
    XmlSerializer s = new XmlSerializer(typeof(Lesson1Test));
    
    // 這句代碼的含義 就是通過序列化對象 對我們類對象進行翻譯 將其翻譯成我們的xml文件 寫入到對應的文件中
    // 第一個參數:文件流對象
    // 第二個參數:想要備翻譯 的對象
    // 注意:翻譯機器的類型 一定要和傳入的對象是一致的 不然會報錯
    s.Serialize(stream, lt);
}

3.運行測試

運行后可以看到如下的文件內容(在?path?文件夾中查看)

可以發(fā)現,只能保存 public 類型的數據

<?xml version="1.0" encoding="utf-8"?>
<Lesson1Test xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <testPublic>10</testPublic>
  <testPUblicStr>123</testPUblicStr>
  <testClass>
    <test1>1</test1>
    <test2>1.1</test2>
    <test3>true</test3>
  </testClass>
  <arrayInt>
    <int>5</int>
    <int>6</int>
    <int>7</int>
  </arrayInt>
  <listInt>
    <int>1</int>
    <int>2</int>
    <int>3</int>
    <int>4</int>
  </listInt>
  <listItem>
    <Lesson1Test2>
      <test1>1</test1>
      <test2>1.1</test2>
      <test3>true</test3>
    </Lesson1Test2>
    <Lesson1Test2>
      <test1>1</test1>
      <test2>1.1</test2>
      <test3>true</test3>
    </Lesson1Test2>
  </listItem>
  <testPro>0</testPro>
</Lesson1Test>

4.自定義節(jié)點名或設置屬性

public class Lesson1Test
{
    [XmlElement("testPublic123123")]  // 將該變量對應的結點名字改為 "testPublic123123"
    public    int          testPublic    = 10;
    private   int          testPrivate   = 11;
    protected int          testProtected = 12;
    internal  int          testInternal  = 13;
    public    string       testPUblicStr = "123";
    public    int          testPro { get; set; }
    public    Lesson1Test2 testClass = new Lesson1Test2();
    public    int[]        arrayInt  = new int[3] { 5, 6, 7 };

    [XmlArray("IntList")]    // 改變數組對應的結點名字
    [XmlArrayItem("Int32")]  // 改變數組成員對應的結點名字
    public List<int> listInt = new List<int>() { 1, 2, 3, 4 };

    public List<Lesson1Test2> listItem = new List<Lesson1Test2>() { new Lesson1Test2(), new Lesson1Test2() };

    // 不支持字典
    // public Dictionary<int, string> testDic = new Dictionary<int, string>() { { 1, "123" } };
}

public class Lesson1Test2
{
    [XmlAttribute("Test1")]    // 將該變量存儲為XML屬性,并改名為 "Test1"
    public int test1 = 1;
    
    [XmlAttribute]             // 將該變量存儲為XML屬性
    public float test2 = 1.1f;
    
    [XmlAttribute]          
    public bool test3 = true;
}
<?xml version="1.0" encoding="utf-8"?>
<Lesson1Test xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <testPublic>10</testPublic>
  <testPUblicStr>123</testPUblicStr>
  <testClass Test1="1" test2="1.1" test3="true" />
  <arrayInt>
    <int>5</int>
    <int>6</int>
    <int>7</int>
  </arrayInt>
  <IntList>
    <Int32>1</Int32>
    <Int32>2</Int32>
    <Int32>3</Int32>
    <Int32>4</Int32>
  </IntList>
  <listItem>
    <Lesson1Test2 Test1="1" test2="1.1" test3="true" />
    <Lesson1Test2 Test1="1" test2="1.1" test3="true" />
  </listItem>
  <testPro>0</testPro>
</Lesson1Test>

?5. 總結:

  • 序列化流程
    1. 有一個想要保存的類對象
    2. 使用 XmlSerializer 序列化該對象
    3. 通過 StreamWriter 配合 using 將數據存儲 寫入文件
  • 注意:
    1. 只能序列化公共成員
    2. 不支持字典序列化
    3. 可以通過特性修改節(jié)點信息或者設置屬性信息
    4. Stream 相關要配合 using 使用

二、XML 反序列化

(一)判斷文件是否存在

using System.IO;

string path = Application.persistentDataPath + "/Lesson1Test.xml";
if(File.Exists(path)) { ... }

(二)反序列化

? 關鍵知識:

  1. using 和 StreamReader
  2. XmlSerializer 的 Deserialize 反序列化方法
using System.Xml.Serialization;

// 讀取文件
using (StreamReader reader = new StreamReader(path))
{
    // 產生了一個 序列化反序列化的翻譯機器
    XmlSerializer s = new XmlSerializer(typeof(Lesson1Test));
    Lesson1Test lt = s.Deserialize(reader) as Lesson1Test;
}

? 運行后調試,可以發(fā)現 List 類型的內容被重復添加,原因是變量?lt?初始化后, List 中有默認值,而反序列化時,Deserialize?方法會往 List 中用?Add?方法添加值,而不是覆蓋原有的值。

Unity XML3——XML序列化,Unity,xml

? 總結:

  1. 判斷文件是否存在?File.Exists()

  2. 文件流獲取?StreamReader reader = new StreamReader(path)

  3. 根據文件流 XmlSerializer 通過 Deserialize 反序列化出對象

? 注意:List 對象如果有默認值,反序列化時不會清空,會往后面添加

三、IXmlSerializable 接口

? C# 的 XmlSerializer 提供了可拓展內容,可以讓一些不能被序列化和反序列化的特殊類能被處理
? 讓特殊類繼承?IXmlSerializable 接口,實現其中的方法即可

(一)回顧序列化與反序列化

using System.IO;
using System.Xml;
using System.Xml.Serialization;

public class TestLesson3 : IXmlSerializable
{
    public int test1;
    public string test2;
}

TestLesson3 t = new TestLesson3();
t.test2 = "123";
string path = Application.persistentDataPath + "/TestLesson3.xml";
// 序列化
using (StreamWriter writer = new StreamWriter(path))
{
    // 序列化"翻譯機器"
    XmlSerializer s = new XmlSerializer(typeof(TestLesson3));
    // 在序列化時  如果對象中的引用成員 為空 那么xml里面是看不到該字段的
    s.Serialize(writer, t);
}
// 反序列化
using (StreamReader reader = new StreamReader(path))
{
    // 序列化"翻譯機器"
    XmlSerializer s = new XmlSerializer(typeof(TestLesson3));
    TestLesson3 t2 = s.Deserialize(reader) as TestLesson3;
}
<?xml version="1.0" encoding="utf-8"?>
<TestLesson3 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <test1>0</test1>
  <test2>123</test2>
</TestLesson3>

(二)繼承 IXmlSerializable 接口

1.繼承接口并實現接口函數

public class TestLesson3 : IXmlSerializable
{
    public int test1;
    public string test2;

    // 返回結構,返回 null 即可,不用過多了解
    public XmlSchema GetSchema()
    {
        return null;
    }

    // 反序列化時 會自動調用的方法
    public void ReadXml(XmlReader reader) { }

    // 序列化時 會自動調用的方法
    public void WriteXml(XmlWriter writer) { }
}

2.WriteXml

public void WriteXml(XmlWriter writer)
{
    // 在里面可以自定義序列化 的規(guī)則

    // 如果要自定義 序列化的規(guī)則 一定會用到 XmlWriter中的一些方法 來進行序列化
    // 1.寫屬性
    writer.WriteAttributeString("test1", this.test1.ToString());
    writer.WriteAttributeString("test2", this.test2);

    // 2.寫節(jié)點
    writer.WriteElementString("test1", this.test1.ToString());
    writer.WriteElementString("test2", this.test2);

    // 3.寫包裹節(jié)點
    XmlSerializer s = new XmlSerializer(typeof(int));
    writer.WriteStartElement("test1");  // 寫 <test1>
    s.Serialize(writer, test1);         // 用序列化翻譯機器寫 test1 的內容
    writer.WriteEndElement();           // 寫 </test1>

    XmlSerializer s2 = new XmlSerializer(typeof(string));
    writer.WriteStartElement("test2");  // 寫 <test2>
    s.Serialize(writer, test2);         // 用序列化翻譯機器寫 test2 的內容
    writer.WriteEndElement();           // 寫 </test2>
}

3.ReadXml

public void ReadXml(XmlReader reader)
{
    // 在里面可以自定義反序列化 的規(guī)則
    // 1.讀屬性
    this.test1 = int.Parse(reader["test1"]);
    this.test2 = reader["test2"];

    // 2.讀節(jié)點
    // 方式一
    reader.Read();                         // 這時是讀到的test1節(jié)點          <test1>
    reader.Read();                         // 這時是讀到的test1節(jié)點包裹的內容  0
    this.test1 = int.Parse(reader.Value);  // 得到當前內容的值=
    reader.Read();                         // 這時讀到的是尾部包裹節(jié)點        </test1>
    reader.Read();                         // 這時是讀到的test2節(jié)點          <test2>
    reader.Read();                         // 這時是讀到的test2節(jié)點包裹的內容  123
    this.test2 = reader.Value;

    // 方式二
    while (reader.Read()) 
    {
        if (reader.NodeType == XmlNodeType.Element) 
        {
            switch (reader.Name) 
            {
                case "test1":
                    reader.Read();
                    this.test1 = int.Parse(reader.Value);
                    break;
                case "test2":
                    reader.Read();
                    this.test2 = reader.Value;
                    break;
            }
        }
    }

    // 3.讀包裹元素節(jié)點
    XmlSerializer s = new XmlSerializer(typeof(int));
    XmlSerializer s2 = new XmlSerializer(typeof(string));

    reader.Read();  // 跳過根節(jié)點
    
    reader.ReadStartElement("test1");     // 讀 <test1>
    test1 = (int)s.Deserialize(reader);   // 用反序列化翻譯機器讀 test1 的內容
    reader.ReadEndElement();              // 讀 </test1>

    reader.ReadStartElement("test2");            // 讀 <test2>
    test2 = s2.Deserialize(reader).ToString();   // 用反序列化翻譯機器讀 test2 的內容
    reader.ReadEndElement();                     // 讀 </test2>
}

四、Dictionary 支持序列化與反序列化

  1. 我們沒辦法修改 C# 自帶的類

  2. 那我們可以重寫一個類繼承 Dictionary,然后讓這個類繼承序列化拓展接口 IXmlSerializable

  3. 實現里面的序列化和反序列化方法即可

public class SerizlizedDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
    public XmlSchema GetSchema() {
        return null;
    }

    // 自定義字典的 反序列化 規(guī)則
    public void ReadXml(XmlReader reader) {
        XmlSerializer keySer   = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSer = new XmlSerializer(typeof(TValue));

        // 要跳過根節(jié)點
        reader.Read();
        // 判斷 當前不是元素節(jié)點 結束 就進行 反序列化
        while (reader.NodeType != XmlNodeType.EndElement) {
            // 反序列化鍵
            TKey key = (TKey)keySer.Deserialize(reader);
            // 反序列化值
            TValue value = (TValue)valueSer.Deserialize(reader);
            // 存儲到字典中
            this.Add(key, value);
        }
    }

    // 自定義 字典的 序列化 規(guī)則
    public void WriteXml(XmlWriter writer) {
        XmlSerializer keySer   = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSer = new XmlSerializer(typeof(TValue));

        foreach (KeyValuePair<TKey, TValue> kv in this) {
            // 鍵值對 的序列化
            keySer.Serialize(writer, kv.Key);
            valueSer.Serialize(writer, kv.Value);
        }
    }
}

(一)序列化測試

public class TestLesson4
{
    public int test1;

    public SerizlizerDictionary<int, string> dic;
}

public class Lesson4 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start() {
        TestLesson4 tl4 = new TestLesson4();
        tl4.dic = new SerizlizerDictionary<int, string>();
        tl4.dic.Add(1, "123");
        tl4.dic.Add(2, "234");
        tl4.dic.Add(3, "345");
        
        string path = Application.persistentDataPath + "/TestLesson4.xml";
        using (StreamWriter writer = new StreamWriter(path)) {
            XmlSerializer s = new XmlSerializer(typeof(TestLesson4));
            s.Serialize(writer, tl4);
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<TestLesson4 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <test1>0</test1>
  <dic>
    <int>1</int>
    <string>123</string>
    <int>2</int>
    <string>234</string>
    <int>3</int>
    <string>345</string>
  </dic>
</TestLesson4>

(二)反序列化測試

void Start() {
    TestLesson4 tl4 = new TestLesson4();
    using (StreamReader reader = new StreamReader(path)) {
        XmlSerializer s = new XmlSerializer(typeof(TestLesson4)); 
        tl4 = s.Deserialize(reader) as TestLesson4;
    }
}

Unity XML3——XML序列化,Unity,xml文章來源地址http://www.zghlxwxcb.cn/news/detail-617477.html

五、自定義 XML 數據管理類

using System;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;

public class XmlDataMgr
{
    // 單例模式
    public static XmlDataMgr Instance { get; } = new XmlDataMgr();

    // 防止外部實例化該管理類
    private XmlDataMgr() { }

    /// <summary>
    /// 保存數據到xml文件中
    /// </summary>
    /// <param name="data">數據對象</param>
    /// <param name="fileName">文件名</param>
    public void SaveData(object data, string fileName) {
        // 1.得到存儲路徑
        string path = Application.persistentDataPath + "/" + fileName + ".xml";
        // 2.存儲文件
        using (StreamWriter writer = new StreamWriter(path)) {
            // 3.序列化
            XmlSerializer s = new XmlSerializer(data.GetType());
            s.Serialize(writer, data);
        }
    }

    /// <summary>
    /// 從xml文件中讀取內容 
    /// </summary>
    /// <param name="type">對象類型</param>
    /// <param name="fileName">文件名</param>
    /// <returns></returns>
    public object LoadData(Type type, string fileName) {
        // 1.首先要判斷文件是否存在
        string path = Application.persistentDataPath + "/" + fileName + ".xml";
        if (!File.Exists(path)) {
            path = Application.streamingAssetsPath + "/" + fileName + ".xml";
            if (!File.Exists(path)) {
                // 如果根本不存在文件 兩個路徑都找過了
                // 那么直接new 一個對象 返回給外部 無非 里面都是默認值
                return Activator.CreateInstance(type);
            }
        }
        // 2.存在就讀取
        using (StreamReader reader = new StreamReader(path)) {
            // 3.反序列化 取出數據
            XmlSerializer s = new XmlSerializer(type);
            return s.Deserialize(reader);
        }
    }
}
  if (!File.Exists(path)) {
            path = Application.streamingAssetsPath + "/" + fileName + ".xml";
            if (!File.Exists(path)) {
                // 如果根本不存在文件 兩個路徑都找過了
                // 那么直接new 一個對象 返回給外部 無非 里面都是默認值
                return Activator.CreateInstance(type);
            }
        }
        // 2.存在就讀取
        using (StreamReader reader = new StreamReader(path)) {
            // 3.反序列化 取出數據
            XmlSerializer s = new XmlSerializer(type);
            return s.Deserialize(reader);
        }
    }
}

到了這里,關于Unity XML3——XML序列化的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【Java萬花筒】選擇最適合您的數據序列化格式:比較 Avro、Protocol Buffers、JSON、XML、MessagePack和BSON

    在當今數據驅動的世界中,高效地處理和傳輸數據變得至關重要。選擇合適的數據序列化格式對于數據存儲、通信和處理的性能至關重要。本文將介紹并比較幾種常用的數據序列化格式,包括Apache Avro、Protocol Buffers、JSON、XML、MessagePack和BSON。通過了解它們的概述、特點、應用

    2024年02月20日
    瀏覽(19)
  • Unity-序列化和反序列化

    序列化是指把對象轉換為字節(jié)序列的過程,而反序列化是指把字節(jié)序列恢復為對象的過程。序列化最主要的用途就是傳遞對象和保存對象。 在Unity中保存和加載、prefab、scene、Inspector窗口、實例化預制體等都使用了序列化與反序列化。 1 自定義的具有Serializable特性的非抽象、

    2024年01月24日
    瀏覽(27)
  • unity 序列化那些事,支持Dictionary序列化

    unity 序列化那些事,支持Dictionary序列化

    目錄 一、普通類型和UnityEngine空間類型序列化 二、數組、list的序列化 三、自定義類的序列化支持 ?四、自定義asset 五、在inspector面板中支持Dictionary序列化 1、在MonoBehaviour中實現Dictionary序列化 ?2、自定義property,讓其在inpsector能夠顯示 3、MonoBehaviour腳本中Dictionary字典的測試

    2024年02月11日
    瀏覽(19)
  • Unity | 序列化(Serialized)和反序列化(NonSerialized)是什么意思

    Unity | 序列化(Serialized)和反序列化(NonSerialized)是什么意思

    一、什么是序列化 官方敘述: 序列化是將對象的狀態(tài)信息轉換為可以存儲或傳輸的形式的過程。 人話敘述: 我們平時輸入的代碼,實際上是不能儲存或者傳輸的,所以我們需要翻譯一下,翻譯成能儲存或者翻譯的文字,這個翻譯的過程叫做序列化。 二、什么要序列化 問題

    2024年02月11日
    瀏覽(28)
  • Unity基于Google Protobuf序列化和反序列化小案例

    Unity基于Google Protobuf序列化和反序列化小案例

    1.協(xié)議定義,簡單實現傳玩家的2D坐標? ? 2.在Unity的Assets目錄下創(chuàng)建一個Plugins文件夾(必須這樣命名),此文件專門存放擴展文件, 再新建文件夾BaseInfolibrary,將Google.Protobuf.dll拖入 ?3.新建一個Test.cs腳本 ?腳本中引入命名空間 代碼改進:通用序列化模板(只用來序列化Message)

    2024年02月15日
    瀏覽(28)
  • Unity序列化

    Unity 的序列化是作用于 C# 類的字段 而非屬性。 序列化規(guī)則 對于需要被序列化的字段,需要遵守一些規(guī)則 訪問修飾符是 public ,或者具有 SerializeField 特性 非 static 非 const 可以被序列化的字段類型 基礎數據結構( int , float , double , bool , string 等) 枚舉(32 位 或 以下) 固定大

    2024年02月06日
    瀏覽(16)
  • Unity——腳本與序列化

    數據序列化有以下幾個主要的應用場景和目的: 1. 持久化存儲:序列化可以將對象或數據結構轉換為字節(jié)序列,使得其可以被存儲在磁盤上或數據庫中。通過序列化,我們可以將應用程序中運行時的數據持久化保存,以便在后續(xù)運行時重新加載和使用。 2. 數據傳輸:序列化

    2024年01月18日
    瀏覽(17)
  • unity中,什么是序列化資源?

    好的,以下是序列化資源(Serialized Asset)的詳細解釋,包括介紹、方法和舉例: 在Unity中,序列化資源是指將Unity場景或預制件中的對象及其屬性保存到磁盤上的文件中,以便在將來將其還原為原始狀態(tài)。序列化資源文件可以包括場景文件(.unity)和預制件文件(.prefab),它

    2024年02月10日
    瀏覽(23)
  • 在Unity中使用Protobuf進行序列化

    在Unity中使用Protobuf進行序列化

    目錄 1.介紹 1.1 什么是Protobuf 1.2 Protobuf和其他數據序列化方案對比 2.下載Protobuf 2.1?方案一 使用VS的Nuget包管理器進行安裝(推薦) 2.1.1安裝Protobuff包 2.1.2拷貝.dll文件 2.2 方案二 從Github下載并自己生成.dll 2.2.1 下載Probuff 2.2.2?VS打開解決方案 2.2.3 安裝.NET SDK 2.2.4 生成.dll文件 3

    2024年04月12日
    瀏覽(30)
  • 【工具篇】SerializableDictionary字典序列化Unity面板顯示

    目錄 一:導入插件 二:創(chuàng)建目標字典類 三:生成數據 ?四:自定義配置數據 Unity本身對字典這種數據結構沒有序列

    2024年02月15日
    瀏覽(42)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包