unity 本地數據讀取

unity使用的5.3版本,本打算用Easy Save 2做存取的,發現學習成本太高了。直接選了二進制存取

後續再修改

測試

        IEnumerator Wait()
        {
            yield return null;
            Game.Scene.AddComponent<ConfigureDataComponent>();
            Game.Scene.AddComponent<RuntimeDataComponent>();
            yield return null;
            var data = Game.Scene.GetComponent<RuntimeDataComponent>().Get<Test>() as Test;
            Log.Debug(data.num.ToString());
            data.num = 9999;
        }

 

數據的存取

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

namespace ETModel
{
	public static class FileHelper
	{
		public static object Load(string path, string type)
		{
			if (!File.Exists(path))
				return Activator.CreateInstance(Type.GetType(type));

			return BytesToObject(File.ReadAllBytes(path))?? Activator.CreateInstance(Type.GetType(type));
		}

		public static object LoadResources(string path, string type)
		{
			var ta = Resources.Load<TextAsset>(path);
			if (ta == null || ta.bytes.Length == 0)
				return Activator.CreateInstance(Type.GetType(type));

			return BytesToObject(ta.bytes)?? Activator.CreateInstance(Type.GetType(type));
		}

		public static void Save<T>(string path, T value)
		{
			var dir = Path.GetDirectoryName(path);
			if (!Directory.Exists(dir))
				Directory.CreateDirectory(dir);

			var bytes = ObjectToBytes(value);
			File.WriteAllBytes(path, bytes);
		}

		public static byte[] ObjectToBytes<T>(T value)
		{
			try
			{
				using (var ms = new MemoryStream())
				{
					IFormatter iFormatter = new BinaryFormatter();
					iFormatter.Serialize(ms, value);
					return ms.ToArray();
				}
			}
			catch(Exception ex)
			{
				Log.Error(ex);
				return null;
			}
		}

		public static object BytesToObject(byte[] bytes)
		{
			try
			{
				using (var ms = new MemoryStream(bytes))
				{
					IFormatter iFormatter = new BinaryFormatter();
					ms.Seek(0, SeekOrigin.Begin);
					return iFormatter.Deserialize(ms);
				}
			}
			catch(Exception ex)
			{
				Log.Error(ex);
				return null;
			}
		}

		public static void GetAllFiles(List<string> files, string dir)
		{
			string[] fls = Directory.GetFiles(dir);
			foreach (string fl in fls)
			{
				files.Add(fl);
			}

			string[] subDirs = Directory.GetDirectories(dir);
			foreach (string subDir in subDirs)
			{
				GetAllFiles(files, subDir);
			}
		}
		
		public static void CleanDirectory(string dir)
		{
			foreach (string subdir in Directory.GetDirectories(dir))
			{
				Directory.Delete(subdir, true);		
			}

			foreach (string subFile in Directory.GetFiles(dir))
			{
				File.Delete(subFile);
			}
		}

		public static void CopyDirectory(string srcDir, string tgtDir)
		{
			DirectoryInfo source = new DirectoryInfo(srcDir);
			DirectoryInfo target = new DirectoryInfo(tgtDir);
	
			if (target.FullName.StartsWith(source.FullName, StringComparison.CurrentCultureIgnoreCase))
			{
				throw new Exception("父目錄不能拷貝到子目錄!");
			}
	
			if (!source.Exists)
			{
				return;
			}
	
			if (!target.Exists)
			{
				target.Create();
			}
	
			FileInfo[] files = source.GetFiles();
	
			for (int i = 0; i < files.Length; i++)
			{
				File.Copy(files[i].FullName, Path.Combine(target.FullName, files[i].Name), true);
			}
	
			DirectoryInfo[] dirs = source.GetDirectories();
	
			for (int j = 0; j < dirs.Length; j++)
			{
				CopyDirectory(dirs[j].FullName, Path.Combine(target.FullName, dirs[j].Name));
			}
		}
	}
}

MD5加密

using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace ETModel
{
	public static class MD5Helper
	{
		public static string FileMD5(string filePath)
		{
			byte[] retVal;
            using (FileStream file = new FileStream(filePath, FileMode.Open))
			{
				MD5 md5 = new MD5CryptoServiceProvider();
				retVal = md5.ComputeHash(file);
			}
			return retVal.ToHex("x2");
		}

		public static string StringMD5(string value)
		{
			MD5 md5 = MD5.Create();
			byte[] byteOld = Encoding.UTF8.GetBytes(value);
			byte[] byteNew = md5.ComputeHash(byteOld);
			StringBuilder sb = new StringBuilder();
			foreach (byte b in byteNew)
			{
				sb.Append(b.ToString("x2"));
			}
			return sb.ToString();

		}
	}
}

 

Resources 文件的配置讀取

using System.Collections.Generic;

namespace ETModel
{
    public interface IConfigureData 
    {
    }

    public class ConfigureDataComponent:Component
    {
        Dictionary<string, IConfigureData> dic = new Dictionary<string, IConfigureData>();
        public void Awake()
        {
            var assemblie = typeof(ConfigureDataComponent).Assembly;
            foreach(var type in assemblie.GetTypes())
            {
                if(type.GetInterface(typeof(IConfigureData).Name)!=null)
                {
                    dic.Add(type.Name, (IConfigureData)FileHelper.LoadResources("Configure/" + type.Name,type.FullName));
                }
            }
        }

        public IConfigureData Get<T>() where T : IConfigureData
        {
            var key = typeof(T).Name;
            if (dic.ContainsKey(key))
                return dic[key];

            return null;
        }
    }

    [ObjectSystem]
    public class ConfigureDataComponentAwakeSystem : AwakeSystem<ConfigureDataComponent>
    {
        public override void Awake(ConfigureDataComponent self)
        {
            self.Awake();
        }
    }
}

全局數據和賬號綁定數據

using System.Collections.Generic;
using UnityEngine;

namespace ETModel
{
    public interface IRuntimeData
    {
        void Update();
    }

    public interface IGlobalData: IRuntimeData
    {
    }

    public interface IAccountData: IRuntimeData
    {
    }

    public class RuntimeDataComponent : Component
    {
        string uid;
        Dictionary<string, IRuntimeData> dic = new Dictionary<string, IRuntimeData>();
        public void Awake()
        {
            var assemblie = typeof(RuntimeDataComponent).Assembly;

            foreach (var type in assemblie.GetTypes())
            {
                if (type.GetInterface(typeof(IGlobalData).Name) != null)
                {
                    var value = (IGlobalData)FileHelper.Load(string.Format("{0}/{1}", Application.persistentDataPath,MD5Helper.StringMD5(type.Name)), type.FullName);
                    dic.Add(type.Name, value);
                }
            }
        }

        public void LoadAllAccountBindingData(string uid)
        {
            this.uid = uid;
            var assemblie = typeof(RuntimeDataComponent).Assembly;

            foreach (var type in assemblie.GetTypes())
            {
                if (type.GetInterface(typeof(IAccountData).Name) != null)
                {
                    var value = (IAccountData)FileHelper.Load(string.Format("{0}/{1}/{2}", Application.persistentDataPath, uid, MD5Helper.StringMD5(type.Name)), type.FullName);
                    dic.Add(type.Name, value);
                }
            }
        }

        public IRuntimeData Get<T>()where T:IRuntimeData
        {
            var key = typeof(T).Name;
            if (dic.ContainsKey(key))
                return dic[key];

            return null;
        }

        public void SaveAll()
        {
            string path;
            foreach (var data in dic.Values)
            {
                if(data.GetType().GetInterface(typeof(IAccountData).Name)!=null)
                {
                     path = string.Format("{0}/{1}/{2}", Application.persistentDataPath, uid, MD5Helper.StringMD5(data.GetType().Name));
                }
                else
                {
                     path = string.Format("{0}/{1}", Application.persistentDataPath, MD5Helper.StringMD5(data.GetType().Name));
                }
                FileHelper.Save(path, data);
            }
        }

        public void Destroy()
        {
            SaveAll();
        }
    }

    [ObjectSystem]
    public class RuntimeDataComponentAwakeSystem : AwakeSystem<RuntimeDataComponent>
    {
        public override void Awake(RuntimeDataComponent self)
        {
            self.Awake();
        }
    }
    [ObjectSystem]
    public class RuntimeDataComponentDestroySystem : DestroySystem<RuntimeDataComponent>
    {
        public override void Destroy(RuntimeDataComponent self)
        {
            self.Destroy();
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章