zoukankan      html  css  js  c++  java
  • Unity3d通用工具类之数据配置加载类-ini配置文件加载

    Unity3d通用工具类之数据配置加载类-ini配置文件加载

    上次我们讲过xml文件的加载配置管理,今天我们换个配置文件,也是比较常见的配置文件.ini格式的数据。

     

    按照国际管理先贴一张啥是.ini文件:

    这里我们分类下,总的来说.ini文件就是里面保存多有数据的头,他的下面包含与之相关的字段数据(采用key-value格式)。

     

    ok,知道格式之后,我们写个IniFile数据管理类:

     

    首先,我们定义他有哪些接口:

     

    肯定他需要加载一个配置文件,那么就定义:

    1.public void LoadFromFile(string fileName)

    还有我们需要取得某个头部下面的key的value,那么就需要定义:

    2.public string GetValue(string sectionName, string key, string defaultValue)

    sectionName代表的是头部名称,key代表键值,value代表对应这个键值的值,如果没有发现这个key,就返回默认的值defaultValue。

     

    因为一个配置文件有多个头部,那么我们就需要定义一个头部类来管理,符合类的单一职责。

     

    所以这里得在定义一个IniSection头部类。

    他包含哪些数据:

      1.头部名称:

      private string sectionName;

      2.键值对:

      private Dictionary<string, string> m_dicKeyValue;

    在IniFile类里面维护一个头部列表缓存:

    3.private List<IniSection> m_sectionList;

    在从文件中加载的时候初始化他,也就是LoadFromFile()方法里面,初始化所有头部的数据。

    IniFile.cs:

     

    public class IniFile
    {
        private List<IniSection> m_sectionList;
        public IniFile()
        {
            m_sectionList = new List<IniSection>(); 
        }
        public void LoadFromFile(string fileName)
        {
            string strFullPath = Application.dataPath + "/" + fileName;
            if (!File.Exists(strFullPath))
            {
                return;
            }
            using (FileStream fs = new FileStream(strFullPath, FileMode.Open))
            {
                LoadFromStream(fs);
            }
        }
        /// <summary>
        /// 取得配置文件中所有的头名称
        /// </summary>
        /// <returns></returns>
        public List<string> GetAllSectionName()
        {
            List<string> sectionList = new List<string>();
            foreach (var sec in m_sectionList)
            {
                sectionList.Add(sec.SectionName.ToLower());
            }
            return sectionList;
        }
       /// <summary>
       /// 取得头部相关的value
       /// </summary>
       /// <param name="sectionName"></param>
       /// <param name="key"></param>
       /// <param name="defaultValue"></param>
       /// <returns></returns>
        public string GetValue(string sectionName, string key, string defaultValue)
        {
            IniSection section = GetSection(sectionName);
            if (section != null)
            {
                return section.GetValue(key, defaultValue);
            }
            return defaultValue;
        }
        private void LoadFromStream(FileStream fs)
        {
            using (StreamReader sr = new StreamReader(fs))
            {
                m_sectionList.Clear();
                string line = null;
                IniSection section = null;
                int equalSignPos = 0;//=号的标记的位置
                string key, value;
                while (true)
                {
                    line = sr.ReadLine();
                    if (null == line)
                    {
                        break;
                    }
                    line = line.Trim();
                    if (line == "")
                    {
                        continue;
                    }
                    //跳过注释
                    if (line.Length >= 2 && line[0] == '/' && line[1] == '/')
                    {
                        continue;
                    }
                    if (line[0] == '[' && line[line.Length - 1] == ']')
                    {
                        //移除首尾的'[]'
                        line = line.Remove(0, 1);
                        line = line.Remove(line.Length - 1, 1);
                        //去SectionList缓存中找是否存在这个Section
                        section = GetSection(line);
                        //如果没有找到就直接new一个
                        if (null == section)
                        {
                            section = new IniSection(line);
                            m_sectionList.Add(section);
                        }
                    }
                    else
                    {
                        //就是在这个头下面的数据字段,key-value格式
                        equalSignPos = line.IndexOf('=');
                        if (equalSignPos != 0)
                        {
                            key = line.Substring(0, equalSignPos);
                            value = line.Substring(equalSignPos + 1, line.Length - equalSignPos - 1);
                            section.AddKeyValue(key, value);
                        }
                        else
                        {
                            Debug.LogWarning("value为空");
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 从缓存中找Section
        /// </summary>
        /// <param name="sectionName"></param>
        /// <returns></returns>
        private IniSection GetSection(string sectionName)
        {
            foreach (var section in m_sectionList)
            {
                if (section.SectionName.ToLower() == sectionName.ToLower())
                {
                    return section;
                }
            }
            return null;
        }
    }

    IniSection.cs:

     

    /// <summary>
    /// ini头部+数据
    /// </summary>
    public class IniSection
    {
        private string sectionName;
        private Dictionary<string, string> m_dicKeyValue;
    
        public string SectionName
        {
            get { return this.sectionName; }
            set { this.sectionName = value; }
        }
    
        public IniSection(string name)
        {
            this.sectionName = name;
            this.m_dicKeyValue = new Dictionary<string, string>();
        }
        /// <summary>
        /// 添加key-value的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void AddKeyValue(string _key,string _value)
        {
            string value = null;
            if (m_dicKeyValue.TryGetValue(_key, out value))
            {
                if (value != null)
                {
                    m_dicKeyValue[_key] = _value;
                }
            }
            else
            {
                m_dicKeyValue.Add(_key, _value);
            }
        }
        /// <summary>
        /// 根据key取得value,如果没有取到就返回默认的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public string GetValue(string key, string defaultValue)
        {
            string value = null;
            m_dicKeyValue.TryGetValue(key, out value);
            if (m_dicKeyValue.TryGetValue(key, out value))
            {
                return value;
            }
            return defaultValue;
        }
    }
    

     

      

     

    Ok,我们进行下测试,写个ServerData.cs类,继承MonoBehavior:

     

    using UnityEngine;
    using System.Collections;
    
    public class ServerData : MonoBehaviour
    {
        public string m_cfgName = "Server.ini";
    
        public void Load()
        {
            IniFile ini = new IniFile();
            ini.LoadFromFile(m_cfgName);
            foreach (var name in ini.GetAllSectionName())
            {
                if (string.Equals(name, "serverinfo"))
                {
                    Debug.Log(ini.GetValue(name, "IP", ""));
                }
            }
        }
        public void Start()
        {
            Load();
        }
    }
    

     

      

     

    可以看到在Console中打印出配置文件的数据:

    这个数据类我写的有问题,这里只是我测试用的,按正常的开发是不能继承mono,因为每个数据类都需要Load,还有会有Destory(Dispose)销毁。

     

    所以定义一个接口:

    public interface IClientData
    {
        bool Load();
        void Destroy();
    }

    让所有的数据类都实现这个接口,然后在搞个数据管理器(单例),在Init里面加载所有的数据类,就拿ServerData来演示:

     

    using UnityEngine;
    using System.Collections;
    
    public class ServerData : IClientData
    {
        public string m_cfgName = "Server.ini";
    
        public bool Load()
        {
            IniFile ini = new IniFile();
            ini.LoadFromFile(m_cfgName);
            foreach (var name in ini.GetAllSectionName())
            {
                if (string.Equals(name, "serverinfo"))
                {
                    Debug.Log(ini.GetValue(name, "IP", ""));
                }
            }
            return true;
        }
        public void Destroy()
        {
    
        }
    }

    ClientDataManager.cs:

     

    using UnityEngine;
    using System.Collections;
    
    public class ClientDataManager
    {
        private static ClientDataManager m_oInstance;
        public static ClientDataManager Instance
        {
            get
            {
                if (m_oInstance == null)
                {
                    m_oInstance = new ClientDataManager();
                }
                return m_oInstance;
            }
        }
        public ServerData ServerData;
        public ClientDataManager()
        {
            ServerData = new ServerData();
        }
        public void Init()
        {
            ServerData.Load();
        }
    }

    Ok,搞个驱动类:Driver.cs:

     

    using UnityEngine;
    using System.Collections;
    
    public class Driver : MonoBehaviour {
    
    	// Use this for initialization
    	void Start () {
            ClientDataManager.Instance.Init();
    	}
    	
    	// Update is called once per frame
    	void Update () {
    	
    	}
    }

    这样,我们假如说在ClientDataManager里面添加所有的数据类,他直接在Driver驱动的时候就全部加载到内存中了。

    上面的执行结果应该跟之前的类似。

     

     

  • 相关阅读:
    php 基本连接mysql数据库和查询数据
    HTTP/2 简介
    MySQL数据库 utf-8与utf8mb4
    AJAX请求中出现OPTIONS请求
    精力充沛的管理者,要不要“闲”下来?
    【转】微信开发出现“该公众号暂时无法提供服务,请稍后再试”的坑
    Nginx笔记(一):安装
    Tomcat分析
    Redis集群搭建与使用
    微信JS-SDK实现上传图片功能
  • 原文地址:https://www.cnblogs.com/CaomaoUnity3d/p/5996196.html
Copyright © 2011-2022 走看看