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;
///
/// 二进制文件管理类
/// 电脑端逻辑 ,webgl不适用读取
/// BitConverter.GetBytes Encoding.UTF8.GetBytes
/// 序列化自定义类 需要加特性 [System.Serializable]
///
public class BinaryManager : BaseManager
{
private BinaryManager() { InitData(); }
///
/// 文件默认存储路径
///
private static readonly string SavePath = Application.persistentDataPath + "/Data/";
///
/// 二进制数据
///
public static string BinaryDataPath = Application.streamingAssetsPath + "/BinaryData/";
///
/// 用于存储所有表
///
private readonly Dictionary tableDic = new Dictionary();
///
/// 加载二进制配置表数据
///
public void InitData()
{
LoadTable();
LoadTable();
LoadTable();
LoadTable();
LoadTable();
LoadTable();
LoadTable();
}
///
/// 加载Excel表的2进制数据到内存中
///
/// 容器类名
/// 数据结构类名
private void LoadTable()
{
//读取二进制文件 解析
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);
}
///
/// 得到一张表的数据
///
/// 容器
///
public T GetTable()where T : class
{
string tableName =typeof(T).Name;
if (tableDic.ContainsKey(tableName))
return tableDic[tableName] as T;
return null;
}
///
/// 保存数据
///
///
///
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();
}
///
/// 读取数据 返回
///
///
///
///
public T LoadData(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;
}
}