用C#写的读写CSV文件
用C#写的读取CSV文件的源代码
CSV文件的格子中包含逗号,引号,换行等,都能轻松读取,而且可以把数据转化成DATATABLE格式
- using System;
- using System.Text;
- using System.Collections;
- using System.IO;
- using System.Data;
- using System.Text.RegularExpressions;
- using System.Diagnostics;
- namespace CsvLib
- {
- #region 类说明信息
- /// <summary>
- /// <DL>
- /// <DT><b>读CSV文件类,读取指定的CSV文件,可以导出DataTable</b></DT>
- /// <DD>
- /// <UL>
- /// </UL>
- /// </DD>
- /// </DL>
- /// <Author>yangzhihong</Author>
- /// <CreateDate>2006/01/16</CreateDate>
- /// <Company></Company>
- /// <Version>1.0</Version>
- /// </summary>
- #endregion
- public class CsvStreamReader
- {
- private ArrayList rowAL; //行链表,CSV文件的每一行就是一个链
- private string fileName; //文件名
- private Encoding encoding; //编码
- public CsvStreamReader()
- {
- this.rowAL = new ArrayList();
- this.fileName = "";
- this.encoding = Encoding.Default;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="fileName">文件名,包括文件路径</param>
- public CsvStreamReader(string fileName)
- {
- this.rowAL = new ArrayList();
- this.fileName = fileName;
- this.encoding = Encoding.Default;
- LoadCsvFile();
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="fileName">文件名,包括文件路径</param>
- /// <param name="encoding">文件编码</param>
- public CsvStreamReader(string fileName,Encoding encoding)
- {
- this.rowAL = new ArrayList();
- this.fileName = fileName;
- this.encoding = encoding;
- LoadCsvFile();
- }
- /// <summary>
- /// 文件名,包括文件路径
- /// </summary>
- public string FileName
- {
- set
- {
- this.fileName = value;
- LoadCsvFile();
- }
- }
- /// <summary>
- /// 文件编码
- /// </summary>
- public Encoding FileEncoding
- {
- set
- {
- this.encoding = value;
- }
- }
- /// <summary>
- /// 获取行数
- /// </summary>
- public int RowCount
- {
- get
- {
- return this.rowAL.Count;
- }
- }
- /// <summary>
- /// 获取列数
- /// </summary>
- public int ColCount
- {
- get
- {
- int maxCol;
- maxCol = 0;
- for (int i = 0;i<this.rowAL.Count;i++)
- {
- ArrayList colAL = (ArrayList) this.rowAL[i];
- maxCol = (maxCol > colAL.Count)?maxCol:colAL.Count;
- }
- return maxCol;
- }
- }
- /// <summary>
- /// 获取某行某列的数据
- /// row:行,row = 1代表第一行
- /// col:列,col = 1代表第一列
- /// </summary>
- public string this[int row,int col]
- {
- get
- {
- //数据有效性验证
- CheckRowValid(row);
- CheckColValid(col);
- ArrayList colAL = (ArrayList) this.rowAL[row-1];
- //如果请求列数据大于当前行的列时,返回空值
- if (colAL.Count < col)
- {
- return "";
- }
- return colAL[col-1].ToString();
- }
- }
- /// <summary>
- /// 根据最小行,最大行,最小列,最大列,来生成一个DataTable类型的数据
- /// 行等于1代表第一行
- /// 列等于1代表第一列
- /// maxrow: -1代表最大行
- /// maxcol: -1代表最大列
- /// </summary>
- public DataTable this[int minRow,int maxRow,int minCol,int maxCol]
- {
- get
- {
- //数据有效性验证
- CheckRowValid(minRow);
- CheckMaxRowValid(maxRow);
- CheckColValid(minCol);
- CheckMaxColValid(maxCol);
- if (maxRow == -1)
- {
- maxRow = RowCount;
- }
- if (maxCol == -1)
- {
- maxCol = ColCount;
- }
- if (maxRow < minRow)
- {
- throw new Exception("最大行数不能小于最小行数");
- }
- if (maxCol < minCol)
- {
- throw new Exception("最大列数不能小于最小列数");
- }
- DataTable csvDT = new DataTable();
- int i;
- int col;
- int row;
- //增加列
- for (i = minCol;i <= maxCol;i++)
- {
- csvDT.Columns.Add(i.ToString());
- }
- for (row = minRow;row <= maxRow;row++)
- {
- DataRow csvDR = csvDT.NewRow();
- i = 0;
- for (col = minCol;col <=maxCol;col++)
- {
- csvDR[i] = this[row,col];
- i++;
- }
- csvDT.Rows.Add(csvDR);
- }
- return csvDT;
- }
- }
- /// <summary>
- /// 检查行数是否是有效的
- /// </summary>
- /// <param name="col"></param>
- private void CheckRowValid(int row)
- {
- if (row <= 0)
- {
- throw new Exception("行数不能小于0");
- }
- if (row > RowCount)
- {
- throw new Exception("没有当前行的数据");
- }
- }
- /// <summary>
- /// 检查最大行数是否是有效的
- /// </summary>
- /// <param name="col"></param>
- private void CheckMaxRowValid(int maxRow)
- {
- if (maxRow <= 0 && maxRow != -1)
- {
- throw new Exception("行数不能等于0或小于-1");
- }
- if (maxRow > RowCount)
- {
- throw new Exception("没有当前行的数据");
- }
- }
- /// <summary>
- /// 检查列数是否是有效的
- /// </summary>
- /// <param name="col"></param>
- private void CheckColValid(int col)
- {
- if (col <= 0)
- {
- throw new Exception("列数不能小于0");
- }
- if (col > ColCount)
- {
- throw new Exception("没有当前列的数据");
- }
- }
- /// <summary>
- /// 检查检查最大列数是否是有效的
- /// </summary>
- /// <param name="col"></param>
- private void CheckMaxColValid(int maxCol)
- {
- if (maxCol <= 0 && maxCol != -1)
- {
- throw new Exception("列数不能等于0或小于-1");
- }
- if (maxCol > ColCount)
- {
- throw new Exception("没有当前列的数据");
- }
- }
- /// <summary>
- /// 载入CSV文件
- /// </summary>
- private void LoadCsvFile()
- {
- //对数据的有效性进行验证
- if (this.fileName == null)
- {
- throw new Exception("请指定要载入的CSV文件名");
- }
- else if (!File.Exists(this.fileName))
- {
- throw new Exception("指定的CSV文件不存在");
- }
- else
- {
- }
- if (this.encoding == null)
- {
- this.encoding = Encoding.Default;
- }
- StreamReader sr = new StreamReader(this.fileName,this.encoding);
- string csvDataLine;
- csvDataLine = "";
- while (true)
- {
- string fileDataLine;
- fileDataLine = sr.ReadLine();
- if (fileDataLine == null)
- {
- break;
- }
- if (csvDataLine == "")
- {
- csvDataLine = fileDataLine;//GetDeleteQuotaDataLine(fileDataLine);
- }
- else
- {
- csvDataLine += "/r/n" + fileDataLine;//GetDeleteQuotaDataLine(fileDataLine);
- }
- //如果包含偶数个引号,说明该行数据中出现回车符或包含逗号
- if (!IfOddQuota(csvDataLine))
- {
- AddNewDataLine(csvDataLine);
- csvDataLine = "";
- }
- }
- sr.Close();
- //数据行出现奇数个引号
- if (csvDataLine.Length > 0)
- {
- throw new Exception("CSV文件的格式有错误");
- }
- }
- /// <summary>
- /// 获取两个连续引号变成单个引号的数据行
- /// </summary>
- /// <param name="fileDataLine">文件数据行</param>
- /// <returns></returns>
- private string GetDeleteQuotaDataLine(string fileDataLine)
- {
- return fileDataLine.Replace("/"/"","/"");
- }
- /// <summary>
- /// 判断字符串是否包含奇数个引号
- /// </summary>
- /// <param name="dataLine">数据行</param>
- /// <returns>为奇数时,返回为真;否则返回为假</returns>
- private bool IfOddQuota(string dataLine)
- {
- int quotaCount;
- bool oddQuota;
- quotaCount = 0;
- for (int i = 0;i < dataLine.Length;i++)
- {
- if (dataLine[i] == '/"')
- {
- quotaCount++;
- }
- }
- oddQuota = false;
- if (quotaCount % 2 == 1)
- {
- oddQuota = true;
- }
- return oddQuota;
- }
- /// <summary>
- /// 判断是否以奇数个引号开始
- /// </summary>
- /// <param name="dataCell"></param>
- /// <returns></returns>
- private bool IfOddStartQuota(string dataCell)
- {
- int quotaCount;
- bool oddQuota;
- quotaCount = 0;
- for (int i = 0;i < dataCell.Length;i++)
- {
- if (dataCell[i] == '/"')
- {
- quotaCount++;
- }
- else
- {
- break;
- }
- }
- oddQuota = false;
- if (quotaCount % 2 == 1)
- {
- oddQuota = true;
- }
- return oddQuota;
- }
- /// <summary>
- /// 判断是否以奇数个引号结尾
- /// </summary>
- /// <param name="dataCell"></param>
- /// <returns></returns>
- private bool IfOddEndQuota(string dataCell)
- {
- int quotaCount;
- bool oddQuota;
- quotaCount = 0;
- for (int i = dataCell.Length -1;i >= 0;i--)
- {
- if (dataCell[i] == '/"')
- {
- quotaCount++;
- }
- else
- {
- break;
- }
- }
- oddQuota = false;
- if (quotaCount % 2 == 1)
- {
- oddQuota = true;
- }
- return oddQuota;
- }
- /// <summary>
- /// 加入新的数据行
- /// </summary>
- /// <param name="newDataLine">新的数据行</param>
- private void AddNewDataLine(string newDataLine)
- {
- Debug.WriteLine("NewLine:" + newDataLine);
- //return;
- ArrayList colAL = new ArrayList();
- string[] dataArray = newDataLine.Split(',');
- bool oddStartQuota; //是否以奇数个引号开始
- string cellData;
- oddStartQuota = false;
- cellData = "";
- for (int i = 0 ;i < dataArray.Length;i++)
- {
- if (oddStartQuota)
- {
- //因为前面用逗号分割,所以要加上逗号
- cellData += "," + dataArray[i];
- //是否以奇数个引号结尾
- if (IfOddEndQuota(dataArray[i]))
- {
- colAL.Add(GetHandleData(cellData));
- oddStartQuota = false;
- continue;
- }
- }
- else
- {
- //是否以奇数个引号开始
- if (IfOddStartQuota(dataArray[i]))
- {
- //是否以奇数个引号结尾,不能是一个双引号,并且不是奇数个引号
- if (IfOddEndQuota(dataArray[i]) && dataArray[i].Length > 2 && !IfOddQuota(dataArray[i]))
- {
- colAL.Add(GetHandleData(dataArray[i]));
- oddStartQuota = false;
- continue;
- }
- else
- {
- oddStartQuota = true;
- cellData = dataArray[i];
- continue;
- }
- }
- else
- {
- colAL.Add(GetHandleData(dataArray[i]));
- }
- }
- }
- if (oddStartQuota)
- {
- throw new Exception("数据格式有问题");
- }
- this.rowAL.Add(colAL);
- }
- /// <summary>
- /// 去掉格子的首尾引号,把双引号变成单引号
- /// </summary>
- /// <param name="fileCellData"></param>
- /// <returns></returns>
- private string GetHandleData(string fileCellData)
- {
- if (fileCellData == "")
- {
- return "";
- }
- if (IfOddStartQuota(fileCellData))
- {
- if (IfOddEndQuota(fileCellData))
- {
- return fileCellData.Substring(1,fileCellData.Length-2).Replace("/"/"","/""); //去掉首尾引号,然后把双引号变成单引号
- }
- else
- {
- throw new Exception("数据引号无法匹配" + fileCellData);
- }
- }
- else
- {
- //考虑形如"" """" """"""
- if (fileCellData.Length >2 && fileCellData[0] == '/"')
- {
- fileCellData = fileCellData.Substring(1,fileCellData.Length-2).Replace("/"/"","/""); //去掉首尾引号,然后把双引号变成单引号
- }
- }
- return fileCellData;
- }
- }
- }
- using System;
- using System.Text;
- using System.Collections;
- using System.IO;
- using System.Data;
- namespace CsvLib
- {
- #region 类说明信息
- /// <summary>
- /// <DL>
- /// <DT><b>写CSV文件类,首先给CSV文件赋值,最后通过Save方法进行保存操作</b></DT>
- /// <DD>
- /// <UL>
- /// </UL>
- /// </DD>
- /// </DL>
- /// <Author>yangzhihong</Author>
- /// <CreateDate>2006/01/16</CreateDate>
- /// <Company></Company>
- /// <Version>1.0</Version>
- /// </summary>
- #endregion
- public class CsvStreamWriter
- {
- private ArrayList rowAL; //行链表,CSV文件的每一行就是一个链
- private string fileName; //文件名
- private Encoding encoding; //编码
- public CsvStreamWriter()
- {
- this.rowAL = new ArrayList();
- this.fileName = "";
- this.encoding = Encoding.Default;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="fileName">文件名,包括文件路径</param>
- public CsvStreamWriter(string fileName)
- {
- this.rowAL = new ArrayList();
- this.fileName = fileName;
- this.encoding = Encoding.Default;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="fileName">文件名,包括文件路径</param>
- /// <param name="encoding">文件编码</param>
- public CsvStreamWriter(string fileName,Encoding encoding)
- {
- this.rowAL = new ArrayList();
- this.fileName = fileName;
- this.encoding = encoding;
- }
- /// <summary>
- /// row:行,row = 1代表第一行
- /// col:列,col = 1代表第一列
- /// </summary>
- public string this[int row,int col]
- {
- set
- {
- //对行进行判断
- if (row <= 0)
- {
- throw new Exception("行数不能小于0");
- }
- else if (row > this.rowAL.Count) //如果当前列链的行数不够,要补齐
- {
- for (int i = this.rowAL.Count + 1;i <= row;i++)
- {
- this.rowAL.Add(new ArrayList());
- }
- }
- else
- {
- }
- //对列进行判断
- if (col <= 0)
- {
- throw new Exception("列数不能小于0");
- }
- else
- {
- ArrayList colTempAL = (ArrayList) this.rowAL[row-1];
- //扩大长度
- if (col > colTempAL.Count)
- {
- for (int i = colTempAL.Count;i <= col;i++)
- {
- colTempAL.Add("");
- }
- }
- this.rowAL[row-1] = colTempAL;
- }
- //赋值
- ArrayList colAL = (ArrayList) this.rowAL[row-1];
- colAL[col-1] = value;
- this.rowAL[row-1] = colAL;
- }
- }
- /// <summary>
- /// 文件名,包括文件路径
- /// </summary>
- public string FileName
- {
- set
- {
- this.fileName = value;
- }
- }
- /// <summary>
- /// 文件编码
- /// </summary>
- public Encoding FileEncoding
- {
- set
- {
- this.encoding = value;
- }
- }
- /// <summary>
- /// 获取当前最大行
- /// </summary>
- public int CurMaxRow
- {
- get
- {
- return this.rowAL.Count;
- }
- }
- /// <summary>
- /// 获取最大列
- /// </summary>
- public int CurMaxCol
- {
- get
- {
- int maxCol;
- maxCol = 0;
- for (int i = 0;i<this.rowAL.Count;i++)
- {
- ArrayList colAL = (ArrayList) this.rowAL[i];
- maxCol = (maxCol > colAL.Count)?maxCol:colAL.Count;
- }
- return maxCol;
- }
- }
- /// <summary>
- /// 添加表数据到CSV文件中
- /// </summary>
- /// <param name="dataDT">表数据</param>
- /// <param name="beginCol">从第几列开始,beginCol = 1代表第一列</param>
- public void AddData(DataTable dataDT,int beginCol)
- {
- if (dataDT == null)
- {
- throw new Exception("需要添加的表数据为空");
- }
- int curMaxRow;
- curMaxRow = this.rowAL.Count;
- for (int i = 0;i < dataDT.Rows.Count;i++)
- {
- for (int j = 0;j <dataDT.Columns.Count;j++)
- {
- this[curMaxRow + i + 1,beginCol + j] = dataDT.Rows[i][j].ToString();
- }
- }
- }
- /// <summary>
- /// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
- /// </summary>
- public void Save()
- {
- //对数据的有效性进行判断
- if (this.fileName == null)
- {
- throw new Exception("缺少文件名");
- }
- else if (File.Exists(this.fileName))
- {
- File.Delete(this.fileName);
- }
- if (this.encoding == null)
- {
- this.encoding = Encoding.Default;
- }
- System.IO.StreamWriter sw = new StreamWriter(this.fileName,false,this.encoding);
- for (int i = 0 ;i < this.rowAL.Count;i++)
- {
- sw.WriteLine(ConvertToSaveLine((ArrayList) this.rowAL[i]));
- }
- sw.Close();
- }
- /// <summary>
- /// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
- /// </summary>
- /// <param name="fileName">文件名,包括文件路径</param>
- public void Save(string fileName)
- {
- this.fileName = fileName;
- Save();
- }
- /// <summary>
- /// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
- /// </summary>
- /// <param name="fileName">文件名,包括文件路径</param>
- /// <param name="encoding">文件编码</param>
- public void Save(string fileName,Encoding encoding)
- {
- this.fileName = fileName;
- this.encoding = encoding;
- Save();
- }
- /// <summary>
- /// 转换成保存行
- /// </summary>
- /// <param name="colAL">一行</param>
- /// <returns></returns>
- private string ConvertToSaveLine(ArrayList colAL)
- {
- string saveLine;
- saveLine = "";
- for (int i = 0;i< colAL.Count;i++)
- {
- saveLine += ConvertToSaveCell(colAL[i].ToString());
- //格子间以逗号分割
- if (i < colAL.Count - 1)
- {
- saveLine += ",";
- }
- }
- return saveLine;
- }
- /// <summary>
- /// 字符串转换成CSV中的格子
- /// 双引号转换成两个双引号,然后首尾各加一个双引号
- /// 这样就不需要考虑逗号及换行的问题
- /// </summary>
- /// <param name="cell">格子内容</param>
- /// <returns></returns>
- private string ConvertToSaveCell(string cell)
- {
- cell = cell.Replace("/"","/"/"");
- return "/"" + cell + "/"";
- }
- }
- }
用C#写的读写CSV文件的更多相关文章
- 用opencsv文件读写CSV文件
首先明白csv文件长啥样儿: 用excel打开就变成表格了,看不到细节 推荐用其它简单粗暴一点儿的编辑器,比如Notepad++, csv文件内容如下: csv文件默认用逗号分隔各列. 有了基础的了解 ...
- python3读写csv文件
python读取CSV文件 python中有一个读写csv文件的包,直接import csv即可.利用这个python包可以很方便对csv文件进行操作,一些简单的用法如下. 1. 读文件 csv_ ...
- 利用JavaCSV API来读写csv文件
http://blog.csdn.net/loongshawn/article/details/53423121 http://javacsv.sourceforge.net/ 转载请注明来源-作者@ ...
- 使用 Apache Commons CSV 读写 CSV 文件
有时候,我们需要读写 CSV 文件,在这里给大家分享Apache Commons CSV,读写 CSV 文件非常方便. 具体官方文档请访问Apache Commons CSV. 官方文档已经写得很详细 ...
- C/C++读写csv文件
博客转载自:http://blog.csdn.net/u012234115/article/details/64465398 C++ 读写CSV文件,注意一下格式即可 #include <ios ...
- JAVA读写CSV文件
最近工作需要,需要读写CSV文件的数据,简单封装了一下 依赖读写CSV文件只需引用`javacsv`这个依赖就可以了 <dependency> <groupId>net.sou ...
- 使用Python读写csv文件的三种方法
Python读写csv文件 觉得有用的话,欢迎一起讨论相互学习~Follow Me 前言 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是 ...
- python读写csv文件
文章链接:https://www.cnblogs.com/cloud-ken/p/8432999.html Python读写csv文件 觉得有用的话,欢迎一起讨论相互学习~Follow Me 前言 逗 ...
- Pandas 基础(4) - 读/写 Excel 和 CSV 文件
这一节将分别介绍读/写 Excel 和 CSV 文件的各种方式: - 读入 CSV 文件 首先是准备一个 csv 文件, 这里我用的是 stock_data.csv, 文件我已上传, 大家可以直接下载 ...
随机推荐
- Java是传值还是传引用
http://www.bccn.net/Article/kfyy/java/jszl/200601/3069.html 对于基本数据类型(整型.浮点型.字符型.布尔型等),传值;对于引用类型(对象.数 ...
- Oracle 删除数据后释放数据文件所占磁盘空间
测试的时候向数据库中插入了大量的数据,测试完成后删除了测试用户以及其全部数据,但是数据文件却没有缩小.经查阅资料之后发现这是 Oracle “高水位”所致,那么怎么把这些数据文件的大小降下来呢?解决办 ...
- css选择器nth-child()和nth-of-type()的应用
<style> .table-striped tbody > tr:nth-child(odd) > td, .table-striped tbody > tr:nth- ...
- Laxcus大数据管理系统2.0(14)- 后记
后记 Laxcus最早源于一个失败的搜索引擎项目,项目最后虽然终止了,但是项目中的部分技术,包括FIXP协议.Diffuse/Converge算法.以及很多新的数据处理理念却得以保留下来,这些成为后来 ...
- Win2D 官方文章系列翻译 - DPI (每英寸点数)和 DIPs(设备独立像素)
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-dpi-dips/ 本文旨在解释物理像素与设备独立像素(DIPs, device independent pi ...
- Android开发-API指南-<application>
<application> 英文原文:http://developer.android.com/guide/topics/manifest/application-element.html ...
- Flash视频播放器开发经验总结
HTTP协议更优 目前几乎所有的视频点播网站全部采用HTTP协议传输数据.因为相对于诸如RTMP等协议来说,HTTP协议是无状态的,数据传输完毕就断开连接,这样服务器就可以腾出资源来服务更多的用户.而 ...
- 学习练习 java 集合
将1—100之间的所有正整数存放在一个List集合中,并将集合中索引位置是10的对象从集合中移除 package com.hanqi; import java.util.*; public class ...
- JavaScript创建表格的两种方式
方式一: var data = [ { id: 1, name: "first", age: 12 }, { id: 2, name: "second", ag ...
- jquery递归遍历xml文件,形成ul-li序列,生成树结构(使用了treeview插件)
treeview插件从这里获得,下载的文件中有demo,看demo文件夹里面的index.html文件就差不多知道如何使用该控件了,在我做的项目里用到的部分代码截图如下(在引用下面的js文件前要先引用 ...