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驱动的时候就全部加载到内存中了。
上面的执行结果应该跟之前的类似。
Unity3d通用工具类之数据配置加载类-ini配置文件加载的更多相关文章
- YTU 2618: B 求类中数据成员的最大值-类模板
2618: B 求类中数据成员的最大值-类模板 时间限制: 1 Sec 内存限制: 128 MB 提交: 430 解决: 300 题目描述 声明一个类模板,类模板中有三个相同类型的数据成员,有一函 ...
- Unity3d通用工具类之数据配置加载类
今天,我们来讲讲游戏中的数据配置加载. 什么是游戏数据加载呢?一般来说游戏中会有场景地图. 按照国际惯例,先贴一张游戏场景的地图: 在这张地图上,我们可以看到有很多正六边形,正六边形上有树木.岩石等. ...
- Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)
上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进 ...
- Util应用程序框架公共操作类(二):数据类型转换公共操作类(源码篇)
上一篇介绍了数据类型转换的一些情况,可以看出,如果不进行封装,有可能导致比较混乱的代码.本文通过TDD方式把数据类型转换公共操作类开发出来,并提供源码下载. 我们在 应用程序框架实战十一:创建VS解决 ...
- 使用File类、StreamRead和StreamWrite读写数据、以及Path类操作文件路径和Directory
1.File类的概念: File类,是一个静态类,主要是来提供一些函数库用的.静态实用类,提供了很多静态的方法,支持对文件的基本操作,包括创建,拷贝,移动,删除和 打开一个文件. File类方法的参量 ...
- C++_类继承1-从一个简单的类开始
面向对象编程的主要目的之一是:提供可重用的代码.尤其是项目很庞大的时候,重用测试过的代码比重新编码代码要好得多. C++提供了更高层次的重用性.其中之一就是继承这个概念. 一些厂商提供了类库.类库由类 ...
- [Yii2.0] 以Yii 2.0风格加载自定义类或命名空间 [配置使用Yii2 autoloader]
Yii 2.0最显著的特征之一就是引入了命名空间,因此对于自定义类的引入方式也同之前有所不同.这篇文章讨论一下如何利用Yii 2.0的自动加载机制,向系统中引入自定义类和命名空间.本文旨在抛砖引玉,如 ...
- springboot的yaml基础语法与取值,配置类,配置文件加载优先级
1.基本语法k:(空格)v:表示一对键值对(一个空格必须有):以空格的缩进来控制层级关系:只要是左对齐的一列数据,都是同一个层级的属性和值也是大小写敏感: server: port: 8081 pat ...
- PyTorch 数据集类 和 数据加载类 的一些尝试
最近在学习PyTorch, 但是对里面的数据类和数据加载类比较迷糊,可能是封装的太好大部分情况下是不需要有什么自己的操作的,不过偶然遇到一些自己导入的数据时就会遇到一些问题,因此自己对此做了一些小实 ...
随机推荐
- CCF CSP 201604-2 俄罗斯方块
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201604-2 俄罗斯方块 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游 ...
- Azkaban(三)Azkaban的使用
界面介绍 首页有四个菜单 projects:最重要的部分,创建一个工程,所有flows将在工程中运行. scheduling:显示定时任务 executing:显示当前运行的任务 history:显示 ...
- ansible安装过程遇到的问题
1.出现Error: ansible requires a json module, none found! SSH password: 192.168.24.15 | FAILED >> ...
- Bootstrap进阶三:jQuery插件概览
单个还是全部引入 JavaScript 插件可以单个引入(使用 Bootstrap 提供的单个 *.js 文件),或者一次性全部引入(使用 bootstrap.js 或压缩版的 bootstrap.m ...
- react篇章-事件处理
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- 防止sql注入的几种方法
一.SQL注入简介 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库. 二.SQL注入攻击的总体 ...
- Qt Quick快速入门之线程基础
首先必须明确的是,Qt中的线程使用是相对复杂的,并不像C#中那么随意,特别是结合串口.网络编程等,使用时稍有不慎就会出问题,然后Qt里面经常出了问题就直接崩溃(这个真是谁用谁知道),所以如果在功能上用 ...
- BZOJ.2428.[HAOI2006]均分数据(随机化贪心/模拟退火)
题目链接 模拟退火: 模拟退火!每次随机一个位置加给sum[]最小的组. 参数真特么玄学啊..气的不想调了(其实就是想刷刷最优解) 如果用DP去算好像更准.. //832kb 428ms #inclu ...
- 【漏洞预警】方程式又一波大规模 0day 攻击泄漏,微软这次要血崩
一大早起床是不是觉得阳光明媚岁月静好?然而网络空间刚刚诞生了一波核弹级爆炸!Shadow Brokers再次泄露出一份震惊世界的机密文档,其中包含了多个精美的 Windows 远程漏洞利用工具,可以覆 ...
- [CC-SUBWAY]Subway Ride
[CC-SUBWAY]Subway Ride 题目大意: 一棵\(n(n\le5\times10^5)\)个点的含重边的树,总边数为\(m(m\le10^6)\),每条边有一个颜色.\(q(q\le5 ...