CsvFileStream.cs

public class CsvFileStream
{
TextReader stream;
bool EOS = false;
bool EOL = false; public CsvFileStream(TextReader s)
{
stream = s;
} public string[] GetNextRow()
{
ArrayList row = new ArrayList();
while (true)
{
string item = GetNextItem();
if (item == null)
return row.Count == ? null : (string[])row.ToArray(typeof(string));
row.Add(item);
}
} string GetNextItem()
{
if (EOL)
{
// previous item was last in line, start new line
EOL = false;
return null;
} bool quoted = false;
bool predata = true;
bool postdata = false;
StringBuilder sb = new StringBuilder(); while (true)
{
char c = GetNextChar(true);
if (EOS)
return sb.Length > ? sb.ToString() : null; if ((postdata || !quoted) && c == ',')
// end of item, return
return sb.ToString(); if ((predata || postdata || !quoted) && (c == '\x0A' || c == '\x0D'))
{
// we are at the end of the line, eat newline characters and exit
EOL = true;
if (c == '\x0D' && GetNextChar(false) == '\x0A')
// new line sequence is 0D0A
GetNextChar(true);
return sb.ToString();
} if (predata && c == ' ')
// whitespace preceeding data, discard
continue; if (predata && c == '"')
{
// quoted data is starting
quoted = true;
predata = false;
continue;
} if (predata)
{
// data is starting without quotes
predata = false;
sb.Append(c);
continue;
} if (c == '"' && quoted)
{
if (GetNextChar(false) == '"')
// double quotes within quoted string means add a quote
sb.Append(GetNextChar(true));
else
// end-quote reached
postdata = true;
continue;
} // all cases covered, character must be data
sb.Append(c);
}
} char[] buffer = new char[];
int pos = ;
int length = ; char GetNextChar(bool eat)
{
if (pos >= length)
{
length = stream.ReadBlock(buffer, , buffer.Length);
if (length == )
{
EOS = true;
return '\0';
}
pos = ;
}
if (eat)
return buffer[pos++];
else
return buffer[pos];
}
}

CsvFileWriter.cs

public class CsvFileWriter
{
private ArrayList rowAL; //行链表,CSV文件的每一行就是一个链
private string fileName; //文件名
private Encoding encoding; //编码 public CsvFileWriter()
{
this.rowAL = new ArrayList();
this.fileName = "";
this.encoding = Encoding.Default;
} /// <summary>
///
/// </summary>
/// <param name="fileName">文件名,包括文件路径</param>
public CsvFileWriter(string fileName)
{
this.rowAL = new ArrayList();
this.fileName = fileName;
this.encoding = Encoding.Default;
} /// <summary>
///
/// </summary>
/// <param name="fileName">文件名,包括文件路径</param>
/// <param name="encoding">文件编码</param>
public CsvFileWriter(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 <= )
{
throw new Exception("行数不能小于0");
}
else if (row > this.rowAL.Count) //如果当前列链的行数不够,要补齐
{
for (int i = this.rowAL.Count + ; i <= row; i++)
{
this.rowAL.Add(new ArrayList());
}
}
else
{
}
//对列进行判断
if (col <= )
{
throw new Exception("列数不能小于0");
}
else
{
ArrayList colTempAL = (ArrayList)this.rowAL[row - ]; //扩大长度
if (col > colTempAL.Count)
{
for (int i = colTempAL.Count; i <= col; i++)
{
colTempAL.Add("");
}
}
this.rowAL[row - ] = colTempAL;
}
//赋值
ArrayList colAL = (ArrayList)this.rowAL[row - ]; colAL[col - ] = value;
this.rowAL[row - ] = 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 = ;
for (int i = ; 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 = ; i < dataDT.Rows.Count; i++)
{
for (int j = ; j < dataDT.Columns.Count; j++)
{
this[curMaxRow + i + , 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 = ; 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 = ; i < colAL.Count; i++)
{
saveLine += ConvertToSaveCell(colAL[i].ToString());
//格子间以逗号分割
if (i < colAL.Count - )
{
saveLine += ",";
}
} return saveLine;
} /// <summary>
/// 字符串转换成CSV中的格子
/// 双引号转换成两个双引号,然后首尾各加一个双引号
/// 这样就不需要考虑逗号及换行的问题
/// </summary>
/// <param name="cell">格子内容</param>
/// <returns></returns>
private string ConvertToSaveCell(string cell)
{
cell = cell.Replace("\"","\"\""); return "\"" + cell + "\"";
//return "";
}
}

CsvFileReader.cs

public class CsvFileReader
{
public static DataTable Parse(string data, bool headers)
{
return Parse(new StringReader(data), headers);
} public static DataTable Parse(string data)
{
return Parse(new StringReader(data));
} public static DataTable Parse(TextReader stream)
{
return Parse(stream, false);
} public static DataTable Parse(TextReader stream, bool headers)
{
DataTable table = new DataTable(); CsvFileStream csv = new CsvFileStream(stream);
string[] row = csv.GetNextRow();
if (row == null) return null; if (headers)
{
foreach (string header in row)
{
if (header != null && header.Length > && !table.Columns.Contains(header))
table.Columns.Add(header, typeof(string));
else
table.Columns.Add(GetNextColumnHeader(table), typeof(string));
}
row = csv.GetNextRow();
} while (row != null)
{
while (row.Length > table.Columns.Count)
table.Columns.Add(GetNextColumnHeader(table), typeof(string));
table.Rows.Add(row);
row = csv.GetNextRow();
}
return table;
} static string GetNextColumnHeader(DataTable table)
{
int c = ;
while (true)
{
string h = "Column" + c++;
if (!table.Columns.Contains(h))
return h;
}
}
}

eg.

TextReader reader = new StreamReader(@"D:\test.csv");
DataTable dt = CsvFileReader.Parse(reader, false);

Create new tool for CSV的更多相关文章

  1. 通过TStringList保存csv文件,只要循环.Add表格里面的每行记录进去,保存即可

    dlgSave := TSaveDialog.Create(nil); dlgSave.filter := 'CSV文件|*.CSV'; dlgSave.DefaultExt := '*.CSV'; ...

  2. python CSV 文件的读写

    1.CSV文件 import csv with open(r"E:\code\0_DataSet\tianchi_2015_mobile_recommand\fresh_comp_offli ...

  3. arcgis engine 监听element的添加、更新和删除事件(使用IMovePointFeedback)

    VB代码: 复制进程序稍作修改变量名和事件逻辑即可使用. Members   AllPropertiesMethodsInheritedNon-inherited Description Displa ...

  4. cocos2d-x 使用UIWebView加载网页(顺便可以看到如何用OC调C++)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=248 前段时间项目中要微博授权登 ...

  5. OBJ解析

    OBJ文件是Alias|Wavefront公司为它的一套基于工作站的3D建模和动画软件"Advanced Visualizer"开发的一种标准3D模型文件格式,很适合用于3D软件模 ...

  6. GP中Geoprocessor.Execute(string name, IVariantArray parameters, ITrackCancel trackCancel)

    在做一个项目的过程中,发现GP运算方法 Execute(string name, IVariantArray parameters, ITrackCancel trackCancel) 与Execut ...

  7. unity 傅老师学习

    辅助插件 I tweeen anmition 补充valueto       https://www.bilibili.com/read/cv103358 开关门 iTween event脚本  iT ...

  8. 3D中的OBJ文件格式详解

    常见到的*.obj文件有两种:第一种是基于COFF(Common Object File Format)格式的OBJ文件(也称目标文件),这种格式用于编译应用程序:第二种是Alias|Wavefron ...

  9. Neo4j 文档

    Graph Fundamentals 基础 Basic concepts to get you going. A graph database can store any kind of data u ...

随机推荐

  1. 【BZOJ 3669】【NOI 2014】魔法森林 LCT+枚举边

    $LCT+枚举$ 复习一下$LCT$模板. 先以$Ai$为关键字$sort$,然后$Ai$从小到大枚举每条边,看能否构成环,构不成则加边,构成则判断,判断过了就切断$Bi$最大的边. 我的边是编号为$ ...

  2. javascript 公共方法 集合

    数组去重: Array.prototype.unique1 = function () { var n = []; //一个新的临时数组 for (var i = 0; i < this.len ...

  3. 状态压缩 HDU1074

    t组数据 n门课程 底限 完成要几天 dp[i] 表示i的二进制数中  1 对应位置课程 完成  最少扣多少分 完成的时间 记录一下怎么下来的 1->2^n 列举 (1<<n)   ...

  4. Mysql-通过case..when实现oracle decode()函数进行多值多结果判断

    oracle的decode函数使用:http://www.cnblogs.com/hwaggLee/p/5335967.html case ..when 函数使用:http://www.cnblogs ...

  5. shell 字符串截取

    ${expression}一共有9种使用方法. ${parameter:-word},如果parameter为空,则用word的值做parameter的缺省值 ${parameter:=word},在 ...

  6. nhibernate 配置nvarchar(max)

     若你真的需要一个nvarchar(max)的sql存储空间时,记得增加 .CustomType("StringClob") Demo:Map(x => x.ContentM ...

  7. Java反射的一些理解

    1.Class对象 VS. 实例对象 在Java中我们一般是这样使用类的:编写类,然后new对象,再调用方法.这里new出来的对象暂且称之为实例对象(instance).其实在这之前还涉及到一个Cla ...

  8. UVa 101 The Blocks Problem Vector基本操作

    UVa 101 The Blocks Problem 一道纯模拟题 The Problem The problem is to parse a series of commands that inst ...

  9. C#的imagebutton

    常常要用到好看一点的button去做,C#本身不提供imagebutton这个控件. 可以用如下方法: 用imagebox添加image图片.对此image进行事件的处理. 有时候所添加的image过 ...

  10. EF-CodeFirst-3搞事

    本文学习旺杰兄的 CodeFirst 系列教程而写.尽量摆脱之前的影子写出自己的理解 表间关系.级联删除 简单玩法已经走通了,但是我就是想搞点事出来.今天来搞搞表间关系和级联删除 表间关系 毫无疑问在 ...