版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/musicvs/article/details/73135681
CSV文件的读取是非常简单的,本篇木头就给CSV新手简单又详细地吹吹水,阿不是,详细地聊聊如何读取CSV文件。
1. 创建CSV文件
首先,用Ron’s Editor创建一个新的CSV文件,不要问我怎么创建,这个常识大家应该有。
或者用记事本新建一个文本文件,然后把后缀改为.CSV,不改也行,这个不影响。
然后点击【文件】->【另存为】,编码选择UTF-8。(Ron’s Editor不需要这么做)
然后给CSV文件随便输点内容,比如:
文件内容是这样的:
ID,Name1,笨木头与游戏开发2,www.benmutou.com3,转载请注明出处
你也可以直接下载木头的CSV文件:
CSVDemo
最后将CSV文件放到Unity项目的
Assets\StreamingAssets目录下,千万记住,这一步不能忘记,否则无法读取文件。
2. 读取文件,保存成一行行的字符串
我的读取方式是, 把文件按行读取,然后再解析每一行的内容,最终以行为单位,保存CSV文件。
先来解决读取文件的问题,如下代码:
- /* 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,Name1,笨木头与游戏开发2,www.benmutou.com3,转载请注明出处
文件的第一行是什么?是每一列数据的字段名,当然,文件内容是我们自己定义的,只是一般情况下第一行都是字段行。
Ron’s Editor默认也是这么做的。
从第二行开始就真正的数据行了,我们来试试读取字段,并输出内容:
- /* 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文件要完全对应。
如下代码所示:
- public class CSVDemo
- {
- public int ID { get; set; }
- public string Name { get; set; }
- }
接下来就要用到这个类了,以后每次修改CSVDemo.csv文件的结构时(比如再加几个字段),那么,CSVDemo类也要做相应的修改。
确实有点麻烦,这也是木头这套CSV读取工具唯一麻烦的地方。
5. 保存CSV文件为对象
既然key字段和value字段的关系已经能确定了,那要保存起来就很简单了,如下代码:
- /* 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值。
最后来测试一下:
- /* 测试读取ID为1的数据 */
- CSVDemo csvDemo1 = csvDataDic[1];
- Debug.Log("ID=" + csvDemo1.ID + ",Name=" + csvDemo1.Name);
尝试获取ID为1的那一行数据,输出日志如下:
成功了,非常完美,啦啦啦。(旁白:突然这么不严肃,真的好么?)
6. 结束
对于新手而言,到目前为止已经足够了,我也不建议新手继续往下看。
先这么用着,等你觉得烦了,不想再这么用if条件一个个key值判断了,想要把代码变得更美丽一些,扩展性更好一些。
那么,这个时候的你,就应该往下看了。
木头会用神奇的方式把那些烦人的步骤去掉,让你再也想不起来。