zoukankan      html  css  js  c++  java
  • C# 读取 CSV 文件,简易实现

    经常用到csv文件,一直用odbc进行读取,但是在unicode编码的时候读取不正确,有时候就算是ANSI编码,如一列数据混编,读取也不正确。不清楚是不是个人电脑的问题。只好自己写个来实现简单的读取,解析含","及"""号CSV文件。

    更新1:使用中发现有些软件生存csv文件时,所有数据默认带有"",以前代码处理带引号空字段数据不正确。

        代码如下,默认用UTF8编码,一次性读取整个CSV文件,若谁试用了此段代码,有问题请反馈给我,谢谢。

            /// <summary>
            /// 读取csv文件到DataTable
            /// </summary>
            /// <param name="filepath"></param>
            /// <returns></returns>
            static private DataTable ReadCsv(string filepath)
            {
                DataTable dt = new DataTable("NewTable");
                DataRow row;
    
                string[] lines = File.ReadAllLines(filepath, Encoding.UTF8);
                string[] head = lines[0].Split(',');
                int cnt = head.Length;
                for (int i = 0; i < cnt; i++)
                {
                    dt.Columns.Add(head[i]);
                }
                for (int i = 0; i < lines.Length; i++)
                {
                    lines[i].Trim();
                    if ((string.IsNullOrWhiteSpace(lines[i])))
                    {
                        continue;
                    }
                    try
                    {
                        row = dt.NewRow();
                        row.ItemArray = GetRow(lines[i], cnt);
                        dt.Rows.Add(row);
                    }
                    catch { }
                }
                return dt;
            }
            /// <summary>
            /// 解析字符串 获取 该行的数据 已经处理,及"号
            /// </summary>
            /// <param name="line">该行的内容</param>
            /// <param name="cnt">总的条目数</param>
            /// <returns></returns>
            static private string[] GetRow(string line, int cnt)
            {
                //line = line.Replace("\"\"", "\""); //若空数据加引号替换不正确
                string[] strs = line.Split(',');
                if (strs.Length == cnt)
                {
                    return RemoveQuotes(strs);
                }
                List<string> list = new List<string>();
                int n = 0, begin = 0;
                bool flag = false;
    
                for (int i = 0; i < strs.Length; i++)
                {
    
                    //没有引号 或者 中间有引号 直接添加
                    if (strs[i].IndexOf("\"") == -1
                        || (flag == false && strs[i][0] != '\"'))
                    {
                        list.Add(strs[i]);
                        continue;
                    }
                    //其实有引号,但该段没有,号,直接添加
                    n = 0;
                    foreach (char ch in strs[i])
                    {
                        if (ch == '\"')
                        {
                            n++;
                        }
                    }
                    if (n % 2 == 0)
                    {
                        list.Add(strs[i]);
                        continue;
                    }
                    //该段有引号 有 ,号,下一段增加后添加
                    flag = true;
                    begin = i;
                    i++;
                    for (i = begin + 1; i < strs.Length; i++)
                    {
                        foreach (char ch in strs[i])
                        {
                            if (ch == '\"')
                            {
                                n++;
                            }
                        }
                        if (strs[i][strs[i].Length - 1] == '\"' && n % 2 == 0)
                        {
                            StringBuilder sb = new StringBuilder();
                            for (; begin <= i; begin++)
                            {
                                sb.Append(strs[begin]);
                                if (begin != i)
                                {
                                    sb.Append(",");
                                }
                            }
                            list.Add(sb.ToString());
                            break;
                        }
                    }
                }
                return RemoveQuotes(list.ToArray());
            }
            /// <summary>
            /// 将解析的数据 去除多余的引号
            /// </summary>
            /// <param name="strs"></param>
            /// <returns></returns>
            static string[] RemoveQuotes(string[] strs)
            {
                for (int i = 0; i < strs.Length; i++)
                {
                    //若该项数据为空 但csv文件中加上双引号
                    if (strs[i] == "\"\"")
                    {
                        strs[i] = "";
                        continue;
                    }
                    //若该项数据头和尾加上引号
                    if (strs[i].Length > 2 && strs[i][0] == '\"' && strs[i][strs[i].Length - 1] == '\"')
                    {
                        strs[i] = strs[i].Substring(1, strs[i].Length - 2);
                    }
                    //若该项数据中间有引号
                    strs[i] = strs[i].Replace("\"\"", "\"");
                }
                return strs;
            }
     
    随性随心,随风随行!
  • 相关阅读:
    20200226 Java IO流——廖雪峰
    20200225 Java 多线程(2)-廖雪峰
    20200225 Java 多线程(1)-廖雪峰
    20200224 尚硅谷ElasticSearch【归档】
    20200224 一 概述
    20200222 尚硅谷Dubbo【归档】
    20200222 四、dubbo原理
    Improved robustness of reinforcement learning policies upon conversion to spiking neuronal network platforms applied to Atari Breakout game
    Reinforcement learning in populations of spiking neurons
    Solving the Distal Reward Problem through Linkage of STDP and Dopamine Signaling
  • 原文地址:https://www.cnblogs.com/adswads/p/3117412.html
Copyright © 2011-2022 走看看