• [Unity工具]CSV工具类


    参考链接:

    https://www.cnblogs.com/lulianqi/p/6385503.html

    http://blog.csdn.net/paul342/article/details/22800137

    说明:

    1.写入一个单元格时,如果含有逗号,则需要将整个字段用双引号括起来;如果里面还有双引号就替换成两个双引号。

    2.写入一行时,末尾要加上 作为行分隔符。

    3.读取时,也要根据上面的写入规则进行解析。

    代码如下:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.IO;
      4 using System.Text;
      5 
      6 public class CSVTool {
      7 
      8     private static char _csvSeparator = ',';
      9     private static bool _trimColumns = false;
     10 
     11     //获取一个单元格的写入格式
     12     public static string GetCSVFormat(string str)
     13     {
     14         string tempStr = str;
     15         if (str.Contains(","))
     16         {
     17             if (str.Contains("""))
     18             {
     19                 tempStr = str.Replace(""", """");
     20             }
     21             tempStr = """ + tempStr + """;
     22         }
     23         return tempStr;
     24     }
     25 
     26     //获取一行的写入格式
     27     public static string GetCSVFormatLine(List<string> strList)
     28     {
     29         string tempStr = "";
     30         for (int i = 0; i < strList.Count - 1; i++)
     31         {
     32             string str = strList[i];
     33             tempStr = tempStr + GetCSVFormat(str) + ",";
     34         }
     35         tempStr = tempStr + GetCSVFormat(strList[strList.Count - 1]) + "
    ";
     36         return tempStr;
     37     }
     38 
     39     //解析一行
     40     public static List<string> ParseLine(string line)
     41     {
     42         StringBuilder _columnBuilder = new StringBuilder();
     43         List<string> Fields = new List<string>();
     44         bool inColumn = false;  //是否是在一个列元素里
     45         bool inQuotes = false;  //是否需要转义
     46         bool isNotEnd = false;  //读取完毕未结束转义
     47         _columnBuilder.Remove(0, _columnBuilder.Length);
     48 
     49         //空行也是一个空元素,一个逗号是2个空元素
     50         if (line == "")
     51         {
     52             Fields.Add("");
     53         }
     54 
     55         // Iterate through every character in the line
     56         for (int i = 0; i < line.Length; i++)
     57         {
     58             char character = line[i];
     59 
     60             // If we are not currently inside a column
     61             if (!inColumn)
     62             {
     63                 // If the current character is a double quote then the column value is contained within
     64                 // double quotes, otherwise append the next character
     65                 inColumn = true;
     66                 if (character == '"')
     67                 {
     68                     inQuotes = true;
     69                     continue;
     70                 }
     71 
     72             }
     73 
     74             // If we are in between double quotes
     75             if (inQuotes)
     76             {
     77                 if ((i + 1) == line.Length)//这个字符已经结束了整行
     78                 {
     79                     if (character == '"') //正常转义结束,且该行已经结束
     80                     {
     81                         inQuotes = false;
     82                         continue;     //当前字符不用添加,跳出后直结束后会添加该元素
     83                     }
     84                     else //异常结束,转义未收尾
     85                     {
     86                         isNotEnd = true;
     87                     }
     88                 }
     89                 else if (character == '"' && line[i + 1] == _csvSeparator) //结束转义,且后面有可能还有数据
     90                 {
     91                     inQuotes = false;
     92                     inColumn = false;
     93                     i++; //跳过下一个字符
     94                 }
     95                 else if (character == '"' && line[i + 1] == '"') //双引号转义
     96                 {
     97                     i++; //跳过下一个字符
     98                 }
     99                 else if (character == '"') //双引号单独出现(这种情况实际上已经是格式错误,为了兼容可暂时不处理)
    100                 {
    101                     throw new Exception("格式错误,错误的双引号转义");
    102                 }
    103                 //其他情况直接跳出,后面正常添加
    104 
    105             }
    106             else if (character == _csvSeparator)
    107                 inColumn = false;
    108 
    109             // If we are no longer in the column clear the builder and add the columns to the list
    110             if (!inColumn) //结束该元素时inColumn置为false,并且不处理当前字符,直接进行Add
    111             {
    112                 Fields.Add(_trimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
    113                 _columnBuilder.Remove(0, _columnBuilder.Length);
    114 
    115             }
    116             else // append the current column
    117                 _columnBuilder.Append(character);
    118         }
    119 
    120         // If we are still inside a column add a new one (标准格式一行结尾不需要逗号结尾,而上面for是遇到逗号才添加的,为了兼容最后还要添加一次)
    121         if (inColumn)
    122         {
    123             if (isNotEnd)
    124             {
    125                 _columnBuilder.Append("
    ");
    126             }
    127             Fields.Add(_trimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
    128         }
    129         else  //如果inColumn为false,说明已经添加,因为最后一个字符为分隔符,所以后面要加上一个空元素
    130         {
    131             Fields.Add("");
    132         }
    133 
    134 
    135         return Fields;
    136     }
    137 
    138     //读取文件
    139     public static List<List<string>> Read(string filePath, Encoding encoding)
    140     {
    141         List<List<string>> result = new List<List<string>>();
    142         string content = File.ReadAllText(filePath, encoding);
    143         string[] lines = content.Split(new string[] { "
    " }, StringSplitOptions.RemoveEmptyEntries);
    144         for (int i = 0; i < lines.Length; i++)
    145         {
    146             List<string> line = ParseLine(lines[i]);
    147             result.Add(line);
    148         }
    149         return result;
    150     }
    151 
    152     //写入文件
    153     public static void Write(string filePath, Encoding encoding, List<List<string>> result)
    154     {
    155         StringBuilder builder = new StringBuilder();
    156         for (int i = 0; i < result.Count; i++)
    157         {
    158             List<string> line = result[i];
    159             builder.Append(GetCSVFormatLine(line));
    160         }
    161         File.WriteAllText(filePath, builder.ToString(), encoding);
    162     }
    163 
    164     //打印
    165     public static void Debug(List<List<string>> result)
    166     {
    167         for (int i = 0; i < result.Count; i++)
    168         {
    169             List<string> line = result[i];
    170             for (int j = 0; j < line.Count; j++)
    171             {
    172                 UnityEngine.Debug.LogWarning(line[j]);
    173             }
    174         }
    175     }
    176 }

    测试:

  • 相关阅读:
    《程序员代码面试指南》第三章 二叉树问题 先序、中序和后序数组两两结合重构二叉树
    《程序员代码面试指南》第三章 二叉树问题 二叉树节点间的最大距离问题
    《程序员代码面试指南》第三章 二叉树问题 在二叉树中找到一个节点的后继节点
    《程序员代码面试指南》第三章 二叉树问题 通过有序数组生成搜索二叉树
    《程序员代码面试指南》第三章 二叉树问题 判断一个树是搜索二叉树和完全二叉树
    《程序员代码面试指南》第三章 二叉树问题 根据后序数组重建搜素二叉树
    《程序员代码面试指南》第三章 二叉树问题 判断二叉树是否为搜素二叉树
    博弈知识入门引导
    ZZNUOJ-2157: 水滴来袭-【干扰阅读-卡模糊精度1e-8的问题】
    ZZNUOJ-2155-单身man集合-【标程做法:数位DP-1-10^8,提前暴力打表法: 砍时间复杂度到10^5】
  • 原文地址:https://www.cnblogs.com/lyh916/p/8588218.html
Copyright © 2020-2023  润新知