数据存储(四)CSV的存储与解析

(一)说明

逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。

(二)特点与注意事项

优点: 1、结构简单,易于理解; 2、解析文本和还原文本的方式较为简洁高效; 3、可以轻松转换为Excel的 .xls 文件,亦可以利用 Excel 以表格的方式进行查阅。相比 .xls 文件,其本身由于只存储文本而不包含表格中的公式等其他附带信息,在相同的文件内容下 CSV 文件可以具有更小的文件体积。

缺点:  1、相比于二进制文件,由于是纯文本存储,体积会比较大; 2、虽然由于数据格式参差不齐,具备基本的安全性,但破解的风险依旧很高。

(三)注意事项

1、可以在Excel中创建保存为 CSV 文件,但是后续对 CSV 文件操作最好用 Notepad++ 等文本编辑器来打开,最好使用 Notepad++;

2、使用Notepad++打开 CSV 文件后,需要将其转码为 UTF-8 格式,这样才能保证文件中的中文被正确显示,而 Excel 存储的文件均不是 UTF-8 编码格式的;

3、在Notepad++中打开 CSV 文件后,会发现多了一个空行,这是 Excel 的存储所导致的。最好把这个空行删掉,以便于程序中计算文件中的真实行数。

(四)简单操作方法

1、读取方法:

            /* 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");

                }

            }

2、写入方法:

/* CSV文件路径 */

            string filePath = Application.streamingAssetsPath + "/CSVDemo.csv";

            /* 读取CSV文件,一行行读取 */

            string[] fileData = File.ReadAllLines(filePath);

            /* 把CSV文件按行存放,每一行的ID作为key值,内容作为value值 */

            Dictionary csvDataDic = new Dictionary();

            /* 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;

            }

3、反射:

/* 把CSV文件按行存放,每一行的ID作为key值,内容作为value值 */

            Dictionary csvDataDic = new Dictionary();

            /* CSV文件路径 */

            string filePath = Application.streamingAssetsPath + "/CSVDemo.csv";

            /* 从CSV文件读取数据 */

            Dictionary> datasDic = LoadCsvFile(filePath);

            /* 遍历每一行数据 */

            foreach (string ID in datasDic.Keys)

            {

                /* CSV的一行数据 */

                Dictionary datas = datasDic[ID];

                /* 读取Csv数据对象的属性 */

                PropertyInfo[] props = typeof(CSVDemo).GetProperties();

                /* 使用反射,将CSV文件的数据赋值给CSV数据对象的相应字段,要求CSV文件的字段名和CSV数据对象的字段名完全相同 */

                CSVDemo obj = new CSVDemo();

                foreach (PropertyInfo pi in props)

                {

                    pi.SetValue(obj, Convert.ChangeType(datas[pi.Name], pi.PropertyType), null);

                }

                /* 按ID-数据的形式存储 */

                csvDataDic[obj.ID] = obj;

            }

4、泛型:

            /// 

            ///读取CSV文件数据(利用反射)

            /// 

            /// CSV数据对象的类型

            /// CSV文件路径

            /// 用于缓存数据的字典

            /// CSV文件所有行内容的数据对象

            private Dictionary LoadCsvData(string csvFilePath)

            {

                Dictionary dic = new Dictionary();

                /* 从CSV文件读取数据 */

                Dictionary> result = LoadCsvFile(csvFilePath);

                /* 遍历每一行数据 */

                foreach (string ID in result.Keys)

                {

                    /* CSV的一行数据 */

                    Dictionary datas = result[ID];

                    /* 读取Csv数据对象的属性 */

                    PropertyInfo[] props = typeof(T_CsvData).GetProperties();

                    /* 使用反射,将CSV文件的数据赋值给CSV数据对象的相应字段,要求CSV文件的字段名和CSV数据对象的字段名完全相同 */

                    T_CsvData obj = Activator.CreateInstance();

                    foreach (PropertyInfo pi in props)

                    {

                        pi.SetValue(obj, Convert.ChangeType(datas[pi.Name], pi.PropertyType), null);

                    }

                    /* 按ID-数据的形式存储 */

                    dic[Convert.ToInt32(ID)] = obj;

                }

                return dic;

            }


            /* 把CSV文件按行存放,每一行的ID作为key值,内容作为value值 */

            Dictionary csvDataDic2 = LoadCsvData(filePath);

            /* 测试读取ID为2的数据 */

            CSVDemo csvDemo2 = csvDataDic2[2];

            Debug.Log("ID=" + csvDemo2.ID + ",Name=" + csvDemo2.Name);


你可能感兴趣的:(数据存储(四)CSV的存储与解析)