在处理数据交换时,经常需要一种简单且通用的方法来存储和读取数据。CSV(Comma-Separated Values,逗号分隔值)文件格式因其简单性和兼容性而广受欢迎。本文将介绍如何使用C#编写两个类,CsvFileWriter
和CsvFileReader
,来实现对CSV文件的读写操作。
CSV文件是一种纯文本文件,其中的每一行包含一个或多个值,这些值通过逗号分隔。每个值代表一个字段(或电子表格中的一列),每行代表一个记录(或电子表格中的一行)。虽然CSV文件的读写操作相对简单,但在处理包含逗号或双引号的值时需要额外注意。
为了将数据写入CSV文件,需要创建一个CsvFileWriter
类。这个类继承自StreamWriter
,用于将数据写入文件。在写入每一行数据时,需要考虑以下特殊情况:
以下是CsvFileWriter
类的基本实现:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ReadWriteCsv
{
public class CsvRow : List<string>
{
public string LineText { get; set; }
}
public class CsvFileWriter : StreamWriter
{
public CsvFileWriter(Stream stream) : base(stream) { }
public CsvFileWriter(string filename) : base(filename) { }
public void WriteRow(CsvRow row)
{
StringBuilder builder = new StringBuilder();
bool firstColumn = true;
foreach (string value in row)
{
if (!firstColumn)
builder.Append(',');
if (value.IndexOfAny(new char[] { ',', '\"' }) != -1)
builder.AppendFormat("\"{0}\"", value.Replace("\"", "\"\""));
else
builder.Append(value);
firstColumn = false;
}
row.LineText = builder.ToString();
WriteLine(row.LineText);
}
}
}
在上述代码中,CsvRow
类用于存储一行CSV数据,而CsvFileWriter
类则负责将CsvRow
对象中的数据写入CSV文件。
为了从CSV文件中读取数据,需要创建一个CsvFileReader
类。这个类继承自StreamReader
,用于从文件中读取数据。在读取每一行数据时,需要考虑以下特殊情况:
以下是CsvFileReader
类的基本实现:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ReadWriteCsv
{
public class CsvFileReader : StreamReader
{
public CsvFileReader(Stream stream) : base(stream) { }
public CsvFileReader(string filename) : base(filename) { }
public bool ReadRow(CsvRow row)
{
row.LineText = ReadLine();
if (String.IsNullOrEmpty(row.LineText)) return false;
int pos = 0;
int rows = 0;
while (pos < row.LineText.Length)
{
string value;
if (row.LineText[pos] == '"')
{
pos++;
int start = pos;
while (pos < row.LineText.Length)
{
if (row.LineText[pos] == '"')
{
pos++;
if (pos >= row.LineText.Length || row.LineText[pos] != '"')
{
pos--;
break;
}
pos++;
}
}
value = row.LineText.Substring(start, pos - start).Replace("\"\"", "\"");
}
else
{
int start = pos;
while (pos < row.LineText.Length && row.LineText[pos] != ',')
pos++;
value = row.LineText.Substring(start, pos - start);
}
if (rows < row.Count)
row[rows] = value;
else
row.Add(value);
rows++;
while (pos < row.LineText.Length && row.LineText[pos] != ',')
pos++;
if (pos < row.LineText.Length)
pos++;
}
while (row.Count > rows)
row.RemoveAt(rows);
return (row.Count > 0);
}
}
}
在上述代码中,CsvFileReader
类负责从CSV文件中读取数据,并将其存储到CsvRow
对象中。
现在已经创建了CsvFileWriter
和CsvFileReader
类,接下来将展示如何使用这些类来写入和读取CSV文件。
void WriteTest()
{
using (CsvFileWriter writer = new CsvFileWriter("WriteTest.csv"))
{
for (int i = 0; i < 100; i++)
{
CsvRow row = new CsvRow();
for (int j = 0; j < 5; j++)
row.Add(String.Format("Column{0}", j));
writer.WriteRow(row);
}
}
}
void ReadTest()
{
using (CsvFileReader reader = new CsvFileReader("ReadTest.csv"))
{
CsvRow row = new CsvRow();
while (reader.ReadRow(row))
{
foreach (string s in row)
{
Console.Write(s);
Console.Write(" ");
}
Console.WriteLine();
}
}
}