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;
            }
     
    随性随心,随风随行!
  • 相关阅读:
    cnblog项目--20190309
    django js引入失效问题
    Python老男孩 day16 函数(六) 匿名函数
    Python老男孩 day16 函数(五) 函数的作用域
    Python老男孩 day15 函数(四) 递归
    Python老男孩 day15 函数(三) 前向引用之'函数即变量'
    Python老男孩 day15 函数(二) 局部变量与全局变量
    Python老男孩 day14 函数(一)
    Python老男孩 day14 字符串格式化
    Python老男孩 day14 集合
  • 原文地址:https://www.cnblogs.com/adswads/p/3117412.html
Copyright © 2011-2022 走看看