1. 程式人生 > >[Unity3D·CSV篇]03.CSV初級快取

[Unity3D·CSV篇]03.CSV初級快取

既然資料物件都有了,要快取起來,真是太簡單了,新建一個專門快取CSV檔案物件的類:

  1. public class CsvDataCached_Newer
  2. {
  3.     /// <summary>
  4.     /// CSVDemo.csv檔案快取物件
  5.     /// </summary>
  6.     public static Dictionary<int, CSVDemo> csvDemoDatas = null;
  7.     static CsvDataCached_Newer()
  8.     {
  9.         /* 快取CSV檔案物件 */
  10.         csvDemoDatas = LoadCsvData<
    CSVDemo>(Application.streamingAssetsPath + "/CSVDemo.csv");
  11.     }
  12.     /// <summary>
  13.     /// 讀取CSV檔案資料(利用反射)
  14.     /// </summary>
  15.     /// <typeparam name="CsvData">CSV資料物件的型別</typeparam>
  16.     /// <param name="csvFilePath">CSV檔案路徑</param>
  17.     /// <param name="csvDatas">用於快取資料的字典</param>
  18.     /// <returns>CSV檔案所有行內容的資料物件</returns>
  19.     private static Dictionary<int, T_CsvData> LoadCsvData<T_CsvData>(string csvFilePath)
  20.     {
  21.         Dictionary<int, T_CsvData> dic = new Dictionary<int, T_CsvData>();
  22.         /* 從CSV檔案讀取資料 */
  23.         Dictionary<string, Dictionary<
    stringstring>> result = LoadCsvFile(csvFilePath);
  24.         /* 遍歷每一行資料 */
  25.         foreach (string ID in result.Keys)
  26.         {
  27.             /* CSV的一行資料 */
  28.             Dictionary<stringstring> datas = result[ID];
  29.             /* 讀取Csv資料物件的屬性 */
  30.             PropertyInfo[] props = typeof(T_CsvData).GetProperties();
  31.             /* 使用反射,將CSV檔案的資料賦值給CSV資料物件的相應欄位,要求CSV檔案的欄位名和CSV資料物件的欄位名完全相同 */
  32.             T_CsvData obj = Activator.CreateInstance<T_CsvData>();
  33.             foreach (PropertyInfo pi in props)
  34.             {
  35.                 pi.SetValue(obj, Convert.ChangeType(datas[pi.Name], pi.PropertyType)null);
  36.             }
  37.             /* 按ID-資料的形式儲存 */
  38.             dic[Convert.ToInt32(ID)] = obj;
  39.         }
  40.         return dic;
  41.     }
  42.     /// <summary>
  43.     /// 讀取CSV檔案
  44.     /// 結果儲存到字典集合,以ID作為Key值,對應每一行的資料,每一行的資料也用字典集合儲存。
  45.     /// </summary>
  46.     /// <param name="filePath"></param>
  47.     /// <returns></returns>
  48.     public static Dictionary<string, Dictionary<stringstring>> LoadCsvFile(string filePath)
  49.     {
  50.         Dictionary<string, Dictionary<stringstring>> result = new Dictionary<string, Dictionary<stringstring>>();
  51.         string[] fileData = File.ReadAllLines(filePath);
  52.         if (fileData.Length < 2)
  53.         {
  54.             return result;
  55.         }
  56.         /* CSV檔案的第一行為Key欄位,第二行開始是資料。第一個欄位一定是ID。 */
  57.         string[] keys = fileData[0].Split(',');
  58.         for (int i = 1; i < fileData.Length; i++)
  59.         {
  60.             string[] line = fileData[i].Split(',');
  61.             /* 以ID為key值,建立一個新的集合,用於儲存當前行的資料 */
  62.             string ID = line[0];
  63.             result[ID] = new Dictionary<stringstring>();
  64.             for (int j = 0; j < line.Length; j++)
  65.             {
  66.                 /* 每一行的資料儲存規則:Key欄位-Value值 */
  67.                 result[ID][keys[j]] = line[j];
  68.             }
  69.         }
  70.         return result;
  71.     }
  72. }
不要緊張,上面兩個看起來很複雜的函式,是之前的那兩個,我只是把它們移到了這個類裡,並且變成了靜態函式。重點要關注的是前面兩段程式碼:
  1.     /// <summary>
  2.     /// CSVDemo.csv檔案快取物件
  3.     /// </summary>
  4.     public static Dictionary<int, CSVDemo> csvDemoDatas = null;
  5.     static CsvDataCached_Newer()
  6.     {
  7.         /* 快取CSV檔案物件 */
  8.         csvDemoDatas = LoadCsvData<CSVDemo>(Application.streamingAssetsPath + "/CSVDemo.csv");
  9.     }
csvDemoDatas屬性用於快取CSVDemo檔案物件,而靜態構造器用於初始化這個屬性。有多少個CSV檔案型別,就寫多少個這樣的屬性。於是,獲取CSV檔案物件的方式就變得很簡單:
  1.         /* 測試讀取ID為2的資料 */
  2.         CSVDemo csvDemo2 = CsvDataCached_Newer.csvDemoDatas[2];
  3.         Debug.Log("ID=" + csvDemo2.ID + ",Name=" + csvDemo2.Name);
測試結果是一樣的: 其實這種快取的方式已經不錯了,接下來木頭要介紹的高階快取方式並不會比這種簡單的方式方便多少。只是,我不希望每次新增一個CSV檔案,就增加一個新的屬性。所以,下一篇的高階快取方式,大家可以不認可。