前言

公司最近开发需要将数据保存到.csv文件(逗号分隔值 文件)中然后上传到ftp服务器上,供我们系统还有客户系统调用,之前完全没有接触过这个,所以先来看看百度的解释:逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。

CSV文件格式的通用标准并不存在,但是在RFC 4180中有基础性的描述。使用的字符编码同样没有被指定,但是7-bitASCII是最基本的通用编码。

简单的说就是逗号隔开 双引号 内即为吗需要的值 数据格式并没有非常统一的标准 但是为了避免出错 我们在开发的时候统一格式是这样的

"name","pwd","date"

"张三","123","2015-09-30"

接下来代码处理中默认格式都是这样的 其实就是纯文本的形式

为什么要用csv文件

这就涉及到数据互通的问题,有些程序支持的表格数据另一些程序并不见得支持,而csv格式的却被大多数的应用程序支持,所以在交换保存数据的时候是个不错的选择。

而在项目开发中 有需要做的处理也不是很简单的

比如有csv文件的读取 数据的转换(如转成datatable),csv文件的重命名 ,csv文件的写入,文件上传到ftp服务器上等等

这里将开发的方法进行了简单的整理,以备不时之需,时间仓促,有不足之处大家多多指点。

注意的点

①文件处理完的时候一定记得关闭释放数据流 否则文件会被占用

②csv并没有严格的标准,多人开发的时候必须规定好格式,统一开发

③文件末尾不能出现空的行,不然会出现datatable溢出情况,这种情况可以代码处理 但是开发中最好约束好方便数据处理

一、将CSV文件的数据读取到DataTable中

首先,我们为了方便管理,在web网站中常常需要读取csv文件中的数据并且显示在网站上方便查询。所以比较方便的办法是见csv文件中的数据转换成datatable形式,代码如下。

/// <summary>
/// 将CSV文件的数据读取到DataTable中
/// </summary>
/// <param name="fileName">CSV文件路径</param>
/// <returns>返回读取了CSV数据的DataTable</returns>
public static DataTable OpenCSV(string filePath)
{
DataTable dt = new DataTable();
FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read); StreamReader sr = new StreamReader(fs, Encoding.UTF8);
//StreamReader sr = new StreamReader(fs, encoding);
//string fileContent = sr.ReadToEnd();
//记录每次读取的一行记录
string strLine = "";
//记录每行记录中的各字段内容
string[] aryLine = null;
string[] tableHead = null;
//标示列数
int columnCount = ;
//标示是否是读取的第一行
bool IsFirst = true;
//逐行读取CSV中的数据
while ((strLine = sr.ReadLine()) != null)
{ if (IsFirst == true)
{
tableHead = strLine.Split(',');
IsFirst = false;
columnCount = tableHead.Length;
//创建列
for (int i = ; i < columnCount; i++)
{
tableHead[i] = tableHead[i].Replace("\"", "");
DataColumn dc = new DataColumn(tableHead[i]);
dt.Columns.Add(dc);
}
}
else
{
aryLine = strLine.Split(',');
DataRow dr = dt.NewRow();
for (int j = ; j < columnCount; j++)
{
dr[j] = aryLine[j].Replace("\"","");
}
dt.Rows.Add(dr);
}
}
if (aryLine != null && aryLine.Length > )
{
dt.DefaultView.Sort = tableHead[] + " " + "DESC";
} sr.Close();
fs.Close();
return dt;
}

二、将DataTable中数据写入到CSV文件中

当然我们一个文件中的数据迁移到另一个文件中或者 直接从数据库中查询的数据 插入到csv文件中 ,有一种方法是通过datatable的形式中转,所以 需要把datatable 转成 csv 代码如下:

/// <summary>
/// 将DataTable中数据写入到CSV文件中
/// </summary>
/// <param name="dt">提供保存数据的DataTable</param>
/// <param name="fileName">CSV的文件路径</param>
public static bool SaveCSV(DataTable dt, string fullPath)
{
try
{
FileInfo fi = new FileInfo(fullPath);
if (!fi.Directory.Exists)
{
fi.Directory.Create();
}
FileStream fs = new FileStream(fullPath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
//StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
string data = "";
//写出列名称
for (int i = ; i < dt.Columns.Count; i++)
{
data += "\"" + dt.Columns[i].ColumnName.ToString() + "\"";
if (i < dt.Columns.Count - )
{
data += ",";
}
}
sw.WriteLine(data);
//写出各行数据
for (int i = ; i < dt.Rows.Count; i++)
{
data = "";
for (int j = ; j < dt.Columns.Count; j++)
{
string str = dt.Rows[i][j].ToString();
str = string.Format("\"{0}\"", str);
data += str;
if (j < dt.Columns.Count - )
{
data += ",";
}
}
sw.WriteLine(data);
}
sw.Close();
fs.Close();
return true;
}
catch {
return false;
}
}

三、修改文件名称

修改文件名称 我们需要保存历史数据 或者实时的知道那个文件被修改 可以通过改变文件的名称 如加上当天的日期等等 方便管理

/// <summary>
/// 修改文件名称
/// </summary>
/// <param name="OldPath">旧的路径 完整的物理路径</param>
/// <param name="NewPath">新的路径</param>
/// <returns></returns>
public static bool ChangeFileName(string OldPath, string NewPath) {
bool re = false;
//OldPath = HttpContext.Current.Server.MapPath(OldPath);虚拟的
//NewPath = HttpContext.Current.Server.MapPath(NewPath);
try {
if (File.Exists(OldPath)) {
File.Move(OldPath, NewPath);
re = true;
}
}
catch {
re = false;
}
return re;
}

四、scv文件的数据写入

直接在网页表单提交数据保存在csv文件中 直接写入文件

 /// <summary>
/// 写入文件
/// </summary>
/// <param name="fullPath"></param>
/// <param name="Data"></param>
/// <returns></returns>
public static bool SaveCSV(string fullPath,string Data)
{
bool re = true;
try
{
FileStream FileStream = new FileStream(fullPath, FileMode.Append);
StreamWriter sw = new StreamWriter(FileStream, System.Text.Encoding.UTF8);
sw.WriteLine(Data);
//清空缓冲区
sw.Flush();
//关闭流
sw.Close();
FileStream.Close();
}
catch {
re = false;
}
return re;
}

五、上传到ftp服务器

把处理好的数据文件上传到ftp服务器供系统调用

/// <summary>
/// 上传文件
/// </summary>
/// <param name="fileinfo">需要上传的文件</param>
/// <param name="targetDir">目标路径</param>
/// <param name="hostname">ftp地址(不带ftp;//)</param>
/// <param name="username">ftp用户名</param>
/// <param name="password">ftp密码</param>
public static bool UploadFtpFile(FileInfo fileinfo, string targetDir, string hostname, string username, string password)
{
bool re = true;
//1. check target
string target;
if (targetDir.Trim() == "")
{
return false;
}
target = fileinfo.Name; //使用临时文件名 string URI = "FTP://" + hostname + "/" + targetDir + "/" + target;
///WebClient webcl = new WebClient();
System.Net.FtpWebRequest ftp = GetRequest(URI, username, password); //设置FTP命令 设置所要执行的FTP命令,
//ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;//假设此处为显示指定路径下的文件列表
ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
//指定文件传输的数据类型
ftp.UseBinary = true;
ftp.UsePassive = true; //告诉ftp文件大小
ftp.ContentLength = fileinfo.Length;
//缓冲大小设置为2KB
const int BufferSize = ;
byte[] content = new byte[BufferSize - + ];
int dataRead; //打开一个文件流 (System.IO.FileStream) 去读上传的文件
using (FileStream fs = fileinfo.OpenRead())
{
try
{
//把上传的文件写入流
using (Stream rs = ftp.GetRequestStream())
{
do
{
//每次读文件流的2KB
dataRead = fs.Read(content, , BufferSize);
rs.Write(content, , dataRead);
} while (!(dataRead < BufferSize));
rs.Close();
} }
catch (Exception ex) {
re = false; }
finally
{
fs.Close();
}
}
return re;
}

本文版权归作者(谢俊)和博客园所有,欢迎转载,转载请标明出处。

原文地址:http://www.cnblogs.com/net-xiejun/

微信开发群

完整源码下载:https://github.com/xiejun-net/weixin

公众账号: