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;
            }
     
    随性随心,随风随行!
  • 相关阅读:
    跨域访问方法列举 jsonp 和 客户端
    session 垃圾回收机制
    php 根据数据权重,得分或者持有数量等进行均衡分配给定数量分配方法
    进程和线程比较
    redis 过期策略分析
    redis 基础知识详解
    tcp/ip 协议
    ip 协议详解
    php redis 分布式类
    nginx打开目录游览功能
  • 原文地址:https://www.cnblogs.com/adswads/p/3117412.html
Copyright © 2011-2022 走看看