1. 程式人生 > >[Unity3D·CSV篇]01.CSV新手級讀取

[Unity3D·CSV篇]01.CSV新手級讀取

CSV檔案的讀取是非常簡單的,本篇木頭就給CSV新手簡單又詳細地吹吹水,阿不是,詳細地聊聊如何讀取CSV檔案。

1. 建立CSV檔案

首先,用Ron’s Editor建立一個新的CSV檔案,不要問我怎麼建立,這個常識大家應該有。或者用記事本新建一個文字檔案,然後把字尾改為.CSV,不改也行,這個不影響。然後點選【檔案】->【另存為】,編碼選擇UTF-8。(Ron’s Editor不需要這麼做)

然後給CSV檔案隨便輸點內容,比如:

檔案內容是這樣的:
ID,Name1,笨木頭與遊戲開發2,www.benmutou.com3,轉載請註明出處
你也可以直接下載木頭的CSV檔案:最後將CSV檔案放到Unity專案的
Assets\StreamingAssets目錄下,千萬記住,這一步不能忘記,否則無法讀取檔案。

2. 讀取檔案,儲存成一行行的字串

 我的讀取方式是, 把檔案按行讀取,然後再解析每一行的內容,最終以行為單位,儲存CSV檔案。先來解決讀取檔案的問題,如下程式碼:
  1. /* CSV檔案路徑 */
  2. string filePath = Application.streamingAssetsPath + "/CSVDemo.csv";
  3. /* 讀取CSV檔案,一行行讀取 */
  4. string[] fileData = File.ReadAllLines(filePath);
CSV檔案需要放在StreamingAssets目錄下(可以有子目錄)才能被成功讀取,為什麼要這麼做?言歸正傳,Application.streamingAssetsPath會自動幫我們組合正確的路徑(自動根據PC、手機平臺組合路徑),讓我們可以正確地找到StreamingAssets目錄下的檔案。而File.ReadAllLines自然不用解釋了,用於讀取檔案,並且按行讀取,儲存為string字串陣列。CSV檔案剛好又是按行儲存的,這樣解析起來會方便很多。

3. Key欄位行和資料行

我們再來回憶一下CSV檔案的內容:
ID,Name1,笨木頭與遊戲開發2,www.benmutou.com3,轉載請註明出處
檔案的第一行是什麼?是每一列資料的欄位名,當然,檔案內容是我們自己定義的,只是一般情況下第一行都是欄位行。Ron’s Editor預設也是這麼做的。從第二行開始就真正的資料行了,我們來試試讀取欄位,並輸出內容:
  1.         /* CSV檔案路徑 */
  2.         string filePath = Application.streamingAssetsPath + "/CSVDemo.csv";
  3.         /* 讀取CSV檔案,一行行讀取 */
  4.         string[]
     fileData = File.ReadAllLines(filePath);
  5.         /* CSV檔案的第一行為Key欄位,先讀取key欄位 */
  6.         string[] keys = fileData[0].Split(',');
  7.         /* 第二行開始是資料 */
  8.         for (int i = 1; i < fileData.Length; i++)
  9.         {
  10.             /* 每一行的內容都是逗號分隔,讀取每一列的值 */
  11.             string[] lineData = fileData[i].Split(',');
  12.             for (int j = 0; j < lineData.Length; j++)
  13.             {
  14.                 Debug.Log("key:" + keys[j] + ",value:" + lineData[j] + "\n");
  15.             }
  16.         }
程式碼解釋如下:a. 檔案第一行是key欄位,每個欄位都是由逗號分割,所以string[] keys = fileData[0].Split(‘,’);就能讀取所有的key欄位,後續需要根據key欄位獲取每列的資料內容;b. 從第二行開始是資料內容,我們再次用逗號分割,這樣就能獲取到某一行的每一列的內容:string[] lineData = fileData[i].Split(‘,’);c. keys陣列和lineData資料的長度一定相同的,所以,第二個for迴圈就能把某一行的資料內容和key欄位對應起來;輸出的日誌如下:可能解釋得有點混亂,這段程式碼總的作用就是,把key欄位,和每一行的資料對應起來。這有什麼作用?等會就知道了。

4. 與CSV檔案對應的類

為了把CSV檔案儲存起來,我們需要有一個類,這個類的結構與CSVDemo.csv檔案要完全對應。如下程式碼所示:
  1. public class CSVDemo
  2. {
  3.     public int ID { get; set; }
  4.     public string Name { get; set; }
  5. }
接下來就要用到這個類了,以後每次修改CSVDemo.csv檔案的結構時(比如再加幾個欄位),那麼,CSVDemo類也要做相應的修改。確實有點麻煩,這也是木頭這套CSV讀取工具唯一麻煩的地方。

5. 儲存CSV檔案為物件

既然key欄位和value欄位的關係已經能確定了,那要儲存起來就很簡單了,如下程式碼:
  1.         /* CSV檔案路徑 */
  2.         string filePath = Application.streamingAssetsPath + "/CSVDemo.csv";
  3.         /* 讀取CSV檔案,一行行讀取 */
  4.         string[] fileData = File.ReadAllLines(filePath);
  5.         /* 把CSV檔案按行存放,每一行的ID作為key值,內容作為value值 */
  6.         Dictionary<int, CSVDemo> csvDataDic = new Dictionary<int, CSVDemo>();
  7.         /* CSV檔案的第一行為Key欄位,先讀取key欄位 */
  8.         string[] keys = fileData[0].Split(',');
  9.         /* 第二行開始是資料 */
  10.         for (int i = 1; i < fileData.Length; i++)
  11.         {
  12.             /* 每一行的內容都是逗號分隔,讀取每一列的值 */
  13.             string[] lineData = fileData[i].Split(',');
  14.             /* CSVDemo類與CSVDemo.csv檔案的key欄位一一對應,用於儲存每一行的資料內容 */
  15.             CSVDemo csvDemo = new CSVDemo();
  16.             for (int j = 0; j < lineData.Length; j++)
  17.             {
  18.                 if(keys[j] == "ID")
  19.                 {
  20.                     csvDemo.ID = Convert.ToInt32(lineData[j]);
  21.                 }
  22.                 else if(keys[j] == "Name")
  23.                 {
  24.                     csvDemo.Name = lineData[j];
  25.                 }
  26.             }
  27.             /* 儲存每一行ID和資料物件的關係 */
  28.             csvDataDic[csvDemo.ID] = csvDemo;
  29.         }
大部分程式碼是和之前一樣的,主要做了以下修改:a. 建立了一個Dictionary<int, CSVDemo> csvDataDic變數,這個變數是為了把CSV檔案儲存起來,以便隨時獲取;b. 在第二個for迴圈中,給每一行都建立了一個CSVDemo物件,然後根據key值來給該物件賦值;c. 最後把每一行 CSVDemo物件都儲存到csvDataDic變數中,以ID作為key值。最後來測試一下:
  1.         /* 測試讀取ID為1的資料 */
  2.         CSVDemo csvDemo1 = csvDataDic[1];
  3.         Debug.Log("ID=" + csvDemo1.ID + ",Name=" + csvDemo1.Name);
嘗試獲取ID為1的那一行資料,輸出日誌如下:成功了,非常完美,啦啦啦。(旁白:突然這麼不嚴肅,真的好麼?)

6. 結束

對於新手而言,到目前為止已經足夠了,我也不建議新手繼續往下看。先這麼用著,等你覺得煩了,不想再這麼用if條件一個個key值判斷了,想要把程式碼變得更美麗一些,擴充套件性更好一些。那麼,這個時候的你,就應該往下看了。木頭會用神奇的方式把那些煩人的步驟去掉,讓你再也想不起來。