YanCheng_Metrology/Assets/Scripts/ProjectBase/BinaryManager/BinaryManager.cs

186 lines
6.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using UnityEngine;
/// <summary>
/// 二进制文件管理类
/// 电脑端逻辑 webgl不适用读取
/// BitConverter.GetBytes Encoding.UTF8.GetBytes
/// 序列化自定义类 需要加特性 [System.Serializable]
/// </summary>
public class BinaryManager : BaseManager<BinaryManager>
{
private BinaryManager() { InitData(); }
/// <summary>
/// 文件默认存储路径
/// </summary>
private static readonly string SavePath = Application.persistentDataPath + "/Data/";
/// <summary>
/// 二进制数据
/// </summary>
public static string BinaryDataPath = Application.streamingAssetsPath + "/BinaryData/";
/// <summary>
/// 用于存储所有表
/// </summary>
private readonly Dictionary<string, object> tableDic = new Dictionary<string, object>();
/// <summary>
/// 加载二进制配置表数据
/// </summary>
public void InitData()
{
LoadTable<TB_SchemeContainer, TB_Scheme>();
LoadTable<TB_ProcessContainer, TB_Process>();
LoadTable<TB_SubProcessContainer, TB_SubProcess>();
LoadTable<TB_SubProcessStepContainer, TB_SubProcessStep>();
LoadTable<TB_SystemContainer, TB_System>();
LoadTable<TB_DeviceTypeContainer, TB_DeviceType>();
LoadTable<TB_ToolAndMaterialContainer, TB_ToolAndMaterial>();
}
/// <summary>
/// 加载Excel表的2进制数据到内存中
/// </summary>
/// <typeparam name="T">容器类名</typeparam>
/// <typeparam name="K">数据结构类名</typeparam>
private void LoadTable<T, K>()
{
//读取二进制文件 解析
using FileStream fs = File.Open(BinaryManager.BinaryDataPath + typeof(K).Name + ".binary", FileMode.Open, FileAccess.Read);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();
int index = 0;
//读取多少行
int count = BitConverter.ToInt32(data, index);
index += 4;
//读取主键变量名 字符串长度
int keyNameLength = BitConverter.ToInt32(data, index);
index += 4;
//读取主键变量名
string keyName = Encoding.UTF8.GetString(data, index, keyNameLength);
index += keyNameLength;
Type contaninerType = typeof(T);
object contaninerObj = Activator.CreateInstance(contaninerType);
//得到数据结构类的Type
Type classType = typeof(K);
//通过反射得到数据结构类 所有字段的信息
FieldInfo[] infos = classType.GetFields();
//读取每一行的信息
for (int i = 0; i < count; i++)
{
object dataObj = Activator.CreateInstance(classType);
foreach (FieldInfo fi in infos)
{
if (fi.FieldType == typeof(int))
{
//将2进制数据转为int 然后给对应字段赋值
fi.SetValue(dataObj, BitConverter.ToInt32(data, index));
index += 4;
}
else if (fi.FieldType == typeof(bool))
{
//将2进制数据转为int 然后给对应字段赋值
fi.SetValue(dataObj, BitConverter.ToBoolean(data, index));
index += 1;
}
else if (fi.FieldType == typeof(float))
{
//将2进制数据转为int 然后给对应字段赋值
fi.SetValue(dataObj, BitConverter.ToSingle(data, index));
index += 4;
}
else if (fi.FieldType == typeof(string))
{
int length = BitConverter.ToInt32(data, index);
index += 4;
fi.SetValue(dataObj, Encoding.UTF8.GetString(data, index, length));
index += length;
}
}
//读取完一行的数据了 应该把这个数据添加到容器对象中
//得到容器对象中的 字典对象
object dicObj = contaninerType.GetField("dataDic").GetValue(contaninerObj);
//通过字典对象得到其中的Add方法
MethodInfo methodInfo = dicObj.GetType().GetMethod("Add");
//
object keyValue = classType.GetField(keyName).GetValue(dataObj);
//Debug.Log(keyValue);
methodInfo.Invoke(dicObj, new object[] { keyValue, dataObj });
}
//把读取完的表记录下来
tableDic.Add(typeof(T).Name, contaninerObj);
}
/// <summary>
/// 得到一张表的数据
/// </summary>
/// <typeparam name="T">容器</typeparam>
/// <returns></returns>
public T GetTable<T>()where T : class
{
string tableName =typeof(T).Name;
if (tableDic.ContainsKey(tableName))
return tableDic[tableName] as T;
return null;
}
/// <summary>
/// 保存数据
/// </summary>
/// <param name="data"></param>
/// <param name="fileName"></param>
public void SaveData(object data, string fileName)
{
if (!Directory.Exists(SavePath))
Directory.CreateDirectory(SavePath);
using FileStream fs = new FileStream(SavePath + fileName + ".binary", FileMode.OpenOrCreate, FileAccess.Write);
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(fs, data);
fs.Flush();
fs.Close();
fs.Dispose();
}
/// <summary>
/// 读取数据 返回
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileName"></param>
/// <returns></returns>
public T LoadData<T>(string fileName)where T : class,new()
{
if (!File.Exists(SavePath + fileName + ".binary"))
{
return default;
}
T data = new T();
using (FileStream fs = File.Open(SavePath + fileName + ".binary",FileMode.Open,FileAccess.Read))
{
BinaryFormatter binaryFormatter =new BinaryFormatter();
data = binaryFormatter.Deserialize(fs) as T;
fs.Close();
fs.Dispose();
}
return data;
}
}