[Unity3D·CSV篇]01.CSV新手级读取

笨木头  2017-06-11 11:08   Unity3D   阅读(335)   0条评论
转载请注明,原文地址:http://www.benmutou.com/archives/2337
文章来源:笨木头与游戏开发
 
CSV文件的读取是非常简单的,本篇木头就给CSV新手简单又详细地吹吹水,阿不是,详细地聊聊如何读取CSV文件。
 

1. 创建CSV文件

首先,用Ron’s Editor创建一个新的CSV文件,不要问我怎么创建,这个常识大家应该有。
 
或者用记事本新建一个文本文件,然后把后缀改为.CSV,不改也行,这个不影响。
然后点击【文件】->【另存为】,编码选择UTF-8。(Ron’s Editor不需要这么做)

然后给CSV文件随便输点内容,比如:

文件内容是这样的:
ID,Name
1,笨木头与游戏开发
2,www.benmutou.com
3,转载请注明出处
你也可以直接下载木头的CSV文件: CSVDemo
 
最后将CSV文件放到Unity项目的Assets\StreamingAssets目录下,千万记住,这一步不能忘记,否则无法读取文件。
 

2. 读取文件,保存成一行行的字符串

 我的读取方式是, 把文件按行读取,然后再解析每一行的内容,最终以行为单位,保存CSV文件。
 
先来解决读取文件的问题,如下代码:

1
2
3
4
5
/* CSV文件路径 */
string filePath = Application.streamingAssetsPath + "/CSVDemo.csv";

/* 读取CSV文件,一行行读取 */
string[] fileData = File.ReadAllLines(filePath);
CSV文件需要放在StreamingAssets目录下(可以有子目录)才能被成功读取,为什么要这么做?
有兴趣的可以看看我这篇文章:http://www.benmutou.com/archives/2094
言归正传,Application.streamingAssetsPath会自动帮我们组合正确的路径(自动根据PC、手机平台组合路径),让我们可以正确地找到StreamingAssets目录下的文件。
而File.ReadAllLines自然不用解释了,用于读取文件,并且按行读取,保存为string字符串数组。
CSV文件刚好又是按行保存的,这样解析起来会方便很多。

3. Key字段行和数据行

我们再来回忆一下CSV文件的内容:
ID,Name
1,笨木头与游戏开发
2,www.benmutou.com
3,转载请注明出处
文件的第一行是什么?是每一列数据的字段名,当然,文件内容是我们自己定义的,只是一般情况下第一行都是字段行。
Ron’s Editor默认也是这么做的。
从第二行开始就真正的数据行了,我们来试试读取字段,并输出内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        /* CSV文件路径 */
        string filePath = Application.streamingAssetsPath + "/CSVDemo.csv";

        /* 读取CSV文件,一行行读取 */
        string[] fileData = File.ReadAllLines(filePath);

        /* CSV文件的第一行为Key字段,先读取key字段 */
        string[] keys = fileData[0].Split(',');

        /* 第二行开始是数据 */
        for (int i = 1; i < fileData.Length; i++)
        {
            /* 每一行的内容都是逗号分隔,读取每一列的值 */
            string[] lineData = fileData[i].Split(',');
            for (int j = 0; j < lineData.Length; j++)
            {
                Debug.Log("key:" + keys[j] + ",value:" + lineData[j] + "\n");
            }
        }
代码解释如下:
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
2
3
4
5
public class CSVDemo
{
    public int ID { get; set; }
    public string Name { get; set; }
}
接下来就要用到这个类了,以后每次修改CSVDemo.csv文件的结构时(比如再加几个字段),那么,CSVDemo类也要做相应的修改。
确实有点麻烦,这也是木头这套CSV读取工具唯一麻烦的地方。

5. 保存CSV文件为对象

既然key字段和value字段的关系已经能确定了,那要保存起来就很简单了,如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
        /* CSV文件路径 */
        string filePath = Application.streamingAssetsPath + "/CSVDemo.csv";

        /* 读取CSV文件,一行行读取 */
        string[] fileData = File.ReadAllLines(filePath);

        /* 把CSV文件按行存放,每一行的ID作为key值,内容作为value值 */
        Dictionary<int, CSVDemo> csvDataDic = new Dictionary<int, CSVDemo>();

        /* CSV文件的第一行为Key字段,先读取key字段 */
        string[] keys = fileData[0].Split(',');

        /* 第二行开始是数据 */
        for (int i = 1; i < fileData.Length; i++)
        {
            /* 每一行的内容都是逗号分隔,读取每一列的值 */
            string[] lineData = fileData[i].Split(',');

            /* CSVDemo类与CSVDemo.csv文件的key字段一一对应,用于保存每一行的数据内容 */
            CSVDemo csvDemo = new CSVDemo();
            for (int j = 0; j < lineData.Length; j++)
            {
                if(keys[j] == "ID")
                {
                    csvDemo.ID = Convert.ToInt32(lineData[j]);
                }
                else if(keys[j] == "Name")
                {
                    csvDemo.Name = lineData[j];
                }
            }

            /* 保存每一行ID和数据对象的关系 */
            csvDataDic[csvDemo.ID] = csvDemo;
        }
大部分代码是和之前一样的,主要做了以下修改:
a. 创建了一个Dictionary<int, CSVDemo> csvDataDic变量,这个变量是为了把CSV文件保存起来,以便随时获取;
b. 在第二个for循环中,给每一行都创建了一个CSVDemo对象,然后根据key值来给该对象赋值;
c. 最后把每一行 CSVDemo对象都保存到csvDataDic变量中,以ID作为key值。
最后来测试一下:

1
2
3
        /* 测试读取ID为1的数据 */
        CSVDemo csvDemo1 = csvDataDic[1];
        Debug.Log("ID=" + csvDemo1.ID + ",Name=" + csvDemo1.Name);
尝试获取ID为1的那一行数据,输出日志如下:
成功了,非常完美,啦啦啦。(旁白:突然这么不严肃,真的好么?)

6. 结束

对于新手而言,到目前为止已经足够了,我也不建议新手继续往下看。
先这么用着,等你觉得烦了,不想再这么用if条件一个个key值判断了,想要把代码变得更美丽一些,扩展性更好一些。
那么,这个时候的你,就应该往下看了。
木头会用神奇的方式把那些烦人的步骤去掉,让你再也想不起来。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注