逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。通常都是纯文本文件。建议使用WORDPAD或是记事本(NOTE)来开启,再则先另存新档后用EXCEL开启,也是方法之一。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace read
{
class Program
{
static void Main(string[] args)
{
List<string[]> read1 = new List<string[]>();
List<string[]> read2 = new List<string[]>();
List<string[]> read3 = new List<string[]>();
//创建一个实例用于缓存CSV数据;
read1 = ReadCSV(@"C:\Users\Administrator\Desktop\C3.csv", true);
//读取CSV数据格式,并将其赋值给缓冲数组;
for (int i = 0; i < read1.Count; i++)
//所用CSV数据中有三维数据
{
Console.Write("{0} ", read1[i][0]);
Console.Write("{0} ", read1[i][1]);
Console.Write("{0} ", read1[i][2]);
Console.WriteLine();
}
read2 = ReadCSV(@"C:\Users\Administrator\Desktop\新建文本文档.txt", true);
//读取文本文档,true表示需要按照一定的分隔符进行读取;
for (int i = 0; i < read2.Count; i++)
//所用文本数据中有三维数据
{
Console.Write("{0} ", read2[i][0]);
Console.Write("{0} ", read2[i][1]);
//为进行分辨这里只显示两列;
Console.WriteLine();
Console.WriteLine();
}
read3 = ReadCSV(@"C:\Users\Administrator\Desktop\新建文本文档.txt", false);
//读取文本文档,false表示读取一行数据,不按分隔符来分辨;
for (int i = 0; i < read3.Count; i++)
//所用CSV数据中有三维数据
{
Console.Write("{0} ", read3[i]);
Console.WriteLine();
}
WriteCSV(@"C:\Users\Administrator\Desktop\C4.csv", true, read1, " ");
//使用分隔符“空格“区别数据;
WriteCSV(@"C:\Users\Administrator\Desktop\C4.csv", true, read1, ",");
//使用分隔符”,“区别数据;
WriteCSV(@"C:\Users\Administrator\Desktop\1.csv", true, read2, ",");
//使用分隔符”,“按照一定的分隔符进行读取;
WriteCSV(@"C:\Users\Administrator\Desktop\2.csv", true, read3, ",");
//使用分隔符”,“不按照一定的分隔符进行读取;
}
/// <summary>
/// 写CSV数据;
/// </summary>
/// <param name="fileTargetName"></param>表示所要写的文件的地址;
/// <param name="apend"></param>表示若要追加数据到该文件中,则为 true;若要覆盖该文件,则为 false。 如果指定的文件不存在,该参数无效,且构造函数将创建一个新文件。
/// <param name="lls"></param>原先所存在数据的数组,是将该数组中的内容写成CSV数据,并保存在相关文件位置;
/// <param name="strSep"></param>分隔符,对于数组中原先的数据按照新的分隔符来保存;
public static void WriteCSV(string fileTargetName, bool apend, List<string[]> lls, string strSep)
{
StreamWriter Write1 = new StreamWriter(fileTargetName, apend, Encoding.Default);
//实例化写入数据流,包含文件的位置,是否需要覆盖还是覆盖;
foreach (var item in lls)
//对于每一个原数组中的内容
{
Write1.WriteLine(string.Join(strSep, item));
// 将后跟行结束符的字符串写入文本字符串或流。
}
Write1.Flush();
//清理当前编写器的所有缓冲区,并使所有缓冲数据写入基础流。
Write1.Close();
// 关闭当前的 StreamWriter 对象和基础流。
}
/// <summary>
/// 读取一个CSV数据文件;
/// </summary>
/// <param name="filePathName"></param>表示所要读取的CSV数据文件的位置;
/// <param name="blSep"></param>表示文件是否需要用分割符分开;
/// <returns></returns>
public static List<string[]> ReadCSV(string filePathName, bool blSep = true)
{
List<string[]> red = new List<string[]>();
//实例化一个中间数组,用来缓存读取的数据;
FileStream fs = new FileStream(filePathName, FileMode.Open, FileAccess.Read);
//文件流实例化,规定文件的打开与操作类型;
StreamReader fileRead = new StreamReader(fs, Encoding.Default);
//读数据流实例操作;
string[] strfile = filePathName.Split('.');
//将文件名拆开,用来辨别最后的文件是什么类型
string strFormat = strfile[strfile.Length - 1];
//用来存储文件的数据类型(后缀);
string strLine = "";
while (strLine != null)
{
strLine = fileRead.ReadLine();
// 从当前流中读取一行字符并将数据作为字符串返回。
if (strLine != null && strLine.Length > 0)
{
if ("csv" == strFormat)
{
red.Add(strLine.Split(','));
//将对象添加到 System.Collections.Generic.List<T> 的结尾处。
}
else
{
if (blSep)
//若不是CSV数据,其他文件的数据;
{
string[] strTemp = strLine.Split(new char[2] { '\t', ' ' });
//通过这两个字符,来对每一行的数据进行分割;比如1 2,在数组中就是占两个数组长度;
List<string> lst = new List<string>();
for (int i = 0; i < strTemp.Length; i++)
{
if (strTemp[i] != "")
{
lst.Add(strTemp[i]);
//添加元素;
}
}
if (lst.Count > 0)
{
red.Add(lst.ToArray());
//将其赋值到新的数组中;
}
}
else
{
string[] str2 = new string[1] { strLine };
//如果不按分隔符分的话,每一行都在数组中只占一个空间;
red.Add(str2);
//添加元素;
}
}
}
}
fileRead.Close();
//关闭读操作;
return red;
//返回数组;
}
}
}
第一张图片是原始的C3.csv数据文件:
下面的是写的C4.csv数据文件,分别为用空格和用逗号分开,由于csv数据是用逗号分开的,所以空格是不区分的:
下面是原始的新建文本文档.txt文件,分别将其按照分隔符和不按分割符来进行操作:
按分割符1.csv:
不按2.csv: