这几天工作要读写CSV文件,CSV格式虽然很简单,为省事想先从网上找一个现成的,但找了半天只有一个看上去可以,至少读写都支持,在此基础上,按照标准修正了一下,标准才是王道。

贴一下CSV格式标准规则,来自百度百科 http://baike.baidu.com/view/468993.htm:

  1 开头是不留空,以行为单位。

  2 可含或不含列名,含列名则居文件第一行。

  3 一行数据不垮行,无空行。

  4 以半角逗号(即,)作分隔符,列为空也要表达其存在。

  5 列内容如存在半角逗号(即,)则用半角引号(即"")将该字段值包含起来。

  6 列内容如存在半角引号(即")则应替换成半角双引号("")转义。

  7 文件读写时引号,逗号操作规则互逆。

  8 内码格式不限,可为ASCII、Unicode或者其他。

  9 不支持特殊字符和中文。

网上看到的,都满足前4条,5和6基本都没考虑,应该只是为处理自己手头工作需要而用。其实只继续努力一下,让它变成通用的,再共享出来就有价值的多。

此类可以读文件或流的数据,返回DataTable。也可以将DataTable处理后保存成csv文件。

public class CsvHelper{public CsvHelper() { }public CsvHelper(string csvFile){this.CsvFile = csvFile;}public string CsvFile { get; set; }public DataTable Read(Stream stream){if (stream.CanSeek) stream.Seek(0, SeekOrigin.Begin);return Read(new StreamReader(stream));}public DataTable Read(){if (String.IsNullOrEmpty(CsvFile)) throw new InvalidOperationException("File name can't be null or empty.");StreamReader reader = new StreamReader(this.CsvFile);return Read(reader);}private DataTable Read(TextReader reader){string line = string.Empty;int lineNumber = 0;DataTable dt = null;try{while ((line = reader.ReadLine()) != null){if (lineNumber == 0){//Create Toledt = CreateDataTable(line);if (dt.Columns.Count == 0) return null;}else{bool added = CreateDataRow(dt, line);if (!added) break;  //Meet the empty rows.}lineNumber++;}}finally{reader.Close();}return dt;}public void Write(DataTable dt){if (String.IsNullOrEmpty(CsvFile)) throw new InvalidOperationException("File name can't be null or empty.");Write(dt, this.CsvFile);}public void Write(DataTable dt, string filename){var sb = WriteString(dt);using (StreamWriter writer = new StreamWriter(filename)){writer.Write(sb);writer.Flush();}}public string WriteString(DataTable dt){if (dt == null) throw new ArgumentNullException("dt");var sb = new System.Text.StringBuilder(9999);for (int i = 0; i < dt.Columns.Count; i++){if (i > 0) sb.Append(',');sb.Append(dt.Columns[i].ColumnName);}sb.Append(Environment.NewLine);foreach (DataRow dr in dt.Rows){for (int i = 0; i < dt.Columns.Count; i++){var text = dr[i] as string;if (text.IndexOf('"') >= 0) text = text.Replace("\"", "\"\"");  //Replace quote to double quotes.if (text.IndexOf(',') >= 0) text = '"' + text + '"';if (i > 0) sb.Append(',');sb.Append(text);}sb.Append(Environment.NewLine);}return sb.ToString();}/// <summary>/// Init DataTable's colomns/// </summary>/// <param name="line"></param>/// <returns></returns>private DataTable CreateDataTable(string line){DataTable dt = new DataTable();foreach (string field in line.Split(',')){dt.Columns.Add(field);}return dt;}private bool CreateDataRow(DataTable dt, string line){DataRow dr = dt.NewRow();string[] fields = new string[dt.Columns.Count];bool add = true;int index = 0;for (int i = 0; i < dt.Columns.Count; i++){if (index >= line.Length) break;var text = ReadField(ref index, line);if (i == 0 && text.Length == 0){add = false;break;}dr[i] = text;}if (add) dt.Rows.Add(dr);return add;}private string ReadField(ref int startIndex, string line){int endIndex;string text;if (line[startIndex] == '"'){startIndex++;endIndex = line.IndexOf("\",", startIndex);     //The normal case, except the end of line.if (endIndex == -1){endIndex = line.IndexOf(',', startIndex);  //Unnormal case, a comma required.if (endIndex == -1) endIndex = line.Length; //Meet string's end.if (line[endIndex - 1] == '"') endIndex--;      //The normal case.}text = line.Substring(startIndex, endIndex - startIndex);startIndex = endIndex + 2;}else{endIndex = line.IndexOf(',', startIndex);if (endIndex == -1) endIndex = line.Length; //Meet string's end.text = line.Substring(startIndex, endIndex - startIndex);startIndex = endIndex + 1;}if (text.Contains("\"\"")) text = text.Replace("\"\"", "\"");return text;}}

处理边界条件,如行尾时,要特别小心。既要保证功能正确,又要确保一定的健壮性和容错性。

这是个不依赖状态的类,也就是其中大部分方法都可以转换为静态方法,看你心情了。希望下次有人像我一样偷懒时,能幸运地google到这篇。

兼容标准的CSV文件读写类相关推荐

  1. [Python从零到壹] 三.语法基础之文件操作、CSV文件读写及面向对象

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. python2.7读取csv文件_13.1. csv — CSV 文件读写 — Python 2.7.18 文档

    13.1.csv - CSV 文件读写¶ 2.3 新版功能. The so-called CSV (Comma Separated Values) format is the most common ...

  3. c++怎么可以在二进制文件中读取带string的数据_文件处理 | csv文件读写

    欢迎关注公众号 学习资料不会少 文件处理 在我们做自动化测试的过程中,常常会将数据文件存放在csv或者Excel文件里边.这一章节内容将给大家介绍,如何使用python进行csv和Excel文件的处理 ...

  4. python 写csv加锁_Python: 对CSV文件读写 和 Md5加密

    1. python 有专门的csv包,直接导入即可. import csv: 2. 直接使用普通文件的open方法 csv_reader=open("e:/python/csv_data/l ...

  5. Tensorflow csv文件读写与分批训练

    Tensorflow-1: csv文件读写与分批训练 原创 2017年04月29日 22:28:23 1509 今天尝试了一下读写csv文件并使用tensorflow训练数据,很方便. 程序训练的一个 ...

  6. VC中海量文件读写类设计与应用(转)

    VC中海量文件读写类设计与应用   沈瑞冰 摘要 本文阐述了海量文件读写的一般方法,并分析了该方法中存在的内存耗尽问题和解决办法,并就此设计了一个海量文件读写类,封装了海量文件读写操作,最后给出了一个 ...

  7. C#常用类库----CSV文件操作类

    using System.Data; using System.IO;namespace DotNet.Utilities {/// <summary>/// CSV文件转换类/// &l ...

  8. VC中海量文件读写类设计与应用

    VC中海量文件读写类设计与应用 文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile().WriteFile ...

  9. day08学习 Python文件函数、CSV文件读写

    文件函数 seek seek(参数1,参数2) - 能够将指针移动指定的偏移量 参数1:移动的偏移量,默认为0 参数2: 0 - 将指针移动到文件开头 ​ 1 - (默认)- 指针指向当前位置 ​ 2 ...

  10. 标准库:csv --- CSV 文件读写

    CSV (Comma Separated Values) 格式是电子表格和数据库中最常见的输入.输出文件格式. csv 模块实现了 CSV 格式表单数据的读写.其提供了诸如"以兼容 Exce ...

最新文章

  1. Springboot使用Maven Profile和Spring Profile进行多环境配置
  2. spring整合mybatis(入门级简单教程4)--扫描mapper类
  3. 世界隐形冠军比拼:德国1307家、美国366家、中国68家
  4. Python基础-re模块
  5. 鸿蒙so系统,鸿蒙手机版JNI实战(JNI开发、SO库生成、SO库使用)
  6. 你买过假芯片吗?元器件专家为您揭秘假冒芯片的套路!
  7. PHP3.2.3 where or,WHERE · ThinkPHP3.2.3完全开发手册 · 看云
  8. 遍历文件夹下所有文件,编辑删除
  9. 8266不通过usb供电_HomePod mini?电源线同样不可拆卸:但或能用USB-C移动电源供电...
  10. Prim和Kruskal算法
  11. Java21天打卡day19-异常
  12. 手把手教你强化学习 (七) 强化学习中的无模型控制
  13. 9.Jenkins 权威指南 --- Jenkins 维护
  14. HTML 管理员登陆小功能 连接数据库
  15. 《孤独的美食家》60家餐厅超全觅食攻略,吃货必收!
  16. BGP多线和双线双IP服务器有什么区别? 哪个网站访问速度更快?
  17. 进入显示器工厂模式的方法! 【95种品牌,维修珍藏资料】
  18. SEM纳米颗粒图像粒径分析 基于ImageJ
  19. 7-108 奇数偶数-zzuli
  20. 专访架构师周爱民:谈企业软件架构设计 1

热门文章

  1. jQuery1.3以上版本@的问题
  2. 顶点计划:辅导员与学生关系讨论
  3. An internal error occurred during: Launching web on MyEclipse Tomcat
  4. Asp.net-MyFirstMVCProject详细解释
  5. 奇怪,为什么在主页上面只列出最近的随笔,而文章呢?
  6. qkerntool使用说明
  7. 利用ComplexHeatmap绘制热图(一)
  8. lisp把多段线顶点连成表_读取多段线顶点并将顶点坐标标到数组中
  9. coredump详解
  10. Egret入门学习日记 --- 第九篇(书中 2.7~2.8节 内容)