在 C# 中读取/写入 CSV/制表符分隔文件

发布于 2024-09-07 07:44:19 字数 192 浏览 1 评论 0原文

我需要从 CSV/制表符分隔文件中读取数据并从 .net 写入此类文件。

困难在于我不知道每个文件的结构,需要将 cvs/tab 文件写入数据表,而 FileHelpers 库似乎不支持。

我已经使用 OLEDB 为 Excel 编写了它,但无法真正找到为此编写选项卡文件的方法,因此将返回到库。

有人可以帮忙提供建议吗?

I need to read from a CSV/Tab delimited file and write to such a file as well from .net.

The difficulty is that I don't know the structure of each file and need to write the cvs/tab file to a datatable, which the FileHelpers library doesn't seem to support.

I've already written it for Excel using OLEDB, but can't really see a way to write a tab file for this, so will go back to a library.

Can anyone help with suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

素染倾城色 2024-09-14 07:44:19

.NET 附带了一个名为 TextFieldParser 类的 CSV/制表符分隔文件解析器。

http://msdn.microsoft.com/en-us /library/microsoft.visualbasic.fileio.textfieldparser.aspx

它支持 CSV 文件的完整 RFC 和非常好的错误报告。

.NET comes with a CSV/tab delminited file parser called the TextFieldParser class.

http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx

It supports the full RFC for CSV files and really good error reporting.

楠木可依 2024-09-14 07:44:19

我使用了这个 CsvReader,它真的很棒并且可配置性很好。它对于字符串和分隔符的各种转义表现良好。其他快速而肮脏的实现中的转义很差,但是这个库非常适合阅读。如果需要,您还可以通过一些额外的代码行添加缓存。

不支持编写,但自己实现相当简单。或者从 此代码

I used this CsvReader, it is really great and well configurable. It behaves well with all kinds of escaping for strings and separators. The escaping in other quick and dirty implementations were poor, but this lib is really great at reading. With a few additional codelines you can also add a cache if you need to.

Writing is not supported but it rather trivial to implement yourself. Or inspire yourself from this code.

天煞孤星 2024-09-14 07:44:19

使用 CsvHelper 的简单示例

using (TextWriter writer = new StreamWriter(filePath)
{
    var csvWriter = new CsvWriter(writer);
    csvWriter.Configuration.Delimiter = "\t";
    csvWriter.Configuration.Encoding = Encoding.UTF8;
    csvWriter.WriteRecords(exportRecords); 
}

Simple example with CsvHelper

using (TextWriter writer = new StreamWriter(filePath)
{
    var csvWriter = new CsvWriter(writer);
    csvWriter.Configuration.Delimiter = "\t";
    csvWriter.Configuration.Encoding = Encoding.UTF8;
    csvWriter.WriteRecords(exportRecords); 
}
心作怪 2024-09-14 07:44:19

以下是几个 CSV 阅读器实现:

http://www.codeproject.com/KB/数据库/CsvReader.aspx

http://www.heikniemi.fi/jhlib/ (只是库的一部分;也包括 CSV 编写器)

我怀疑是否有一种标准方法可以“自动”将 CSV 转换为 DataTable 或数据库,您必须编写代码才能做到这一点。如何做到这一点是一个单独的问题。

Here are a couple CSV reader implementations:

http://www.codeproject.com/KB/database/CsvReader.aspx

http://www.heikniemi.fi/jhlib/ (just one part of the library; includes a CSV writer too)

I doubt there is a standard way to convert CSV to DataTable or database 'automatically', you'll have to write code to do that. How to do that is a separate question.

拧巴小姐 2024-09-14 07:44:19

您将在代码中创建数据表,并且(假设有标题行)可以根据文件中的第一行创建列。之后,只需读取文件并根据其中的数据创建新行即可。

您可以使用这样的内容:

DataTable Tbl = new DataTable();
using(StreamReader sr = new StreamReader(path))
{
  int count = 0;
  string headerRow = sr.Read();
  string[] headers = headerRow.split("\t") //Or ","
  foreach(string h in headers)
  {
    DataColumn dc = new DataColumn(h);
    Tbl.Columns.Add(dc);
    count++;
  }
  while(sr.Peek())
  {
    string data = sr.Read();
    string[] cells = data.Split("\t") 
    DataRow row = new DataRow();
    foreach(string c in cells)
    {
      row.Columns.Add(c);
    }
    Tbl.Rows.Add(row);
  }
}

上面的代码尚未编译,因此可能有一些错误,但它应该让您走上正确的轨道。

You'll create your datatable in code, and (presuming a header row) can create columns based on your first line in the file. After that, it will simply be a matter of reading the file and creating new rows based on the data therein.

You could use something like this:

DataTable Tbl = new DataTable();
using(StreamReader sr = new StreamReader(path))
{
  int count = 0;
  string headerRow = sr.Read();
  string[] headers = headerRow.split("\t") //Or ","
  foreach(string h in headers)
  {
    DataColumn dc = new DataColumn(h);
    Tbl.Columns.Add(dc);
    count++;
  }
  while(sr.Peek())
  {
    string data = sr.Read();
    string[] cells = data.Split("\t") 
    DataRow row = new DataRow();
    foreach(string c in cells)
    {
      row.Columns.Add(c);
    }
    Tbl.Rows.Add(row);
  }
}

The above code has not been compiled, so it may have some errors, but it should get you on the right track.

夏の忆 2024-09-14 07:44:19

您可以读取和写入 csv 文件..
这可能对您有帮助。

将分割字符传递给此参数“serparationChar”

示例:-

    private DataTable dataTable = null;
    private bool IsHeader = true;
    private string headerLine = string.Empty;
    private List<string> AllLines = new List<string>();
    private StringBuilder sb = new StringBuilder();
    private char seprateChar = ',';


    public DataTable ReadCSV(string path, bool IsReadHeader, char serparationChar)
    {
        seprateChar = serparationChar;
        IsHeader = IsReadHeader;
        using (StreamReader sr = new StreamReader(path,Encoding.Default))
        {
            while (!sr.EndOfStream)
            {
              AllLines.Add( sr.ReadLine());
            }
            createTemplate(AllLines);
        }

        return dataTable;
    }
    public void WriteCSV(string path,DataTable dtable,char serparationChar)
    {
        AllLines = new List<string>();
        seprateChar = serparationChar;
        List<string> StableHeadrs = new List<string>();
        int colCount = 0;
        using (StreamWriter sw = new StreamWriter(path))
        {
            foreach (DataColumn col in dtable.Columns)
            {
                sb.Append(col.ColumnName);
                if(dataTable.Columns.Count-1 > colCount)
                sb.Append(seprateChar);
                colCount++;
            }
            AllLines.Add(sb.ToString());

            for (int i = 0; i < dtable.Rows.Count; i++)
            {
                sb.Clear();
                for (int j = 0; j < dtable.Columns.Count; j++)
                {
                    sb.Append(Convert.ToString(dtable.Rows[i][j]));
                    if (dataTable.Columns.Count - 1 > j)
                    sb.Append(seprateChar);
                }
                AllLines.Add(sb.ToString());
            }

            foreach (string dataline in AllLines)
            {
                sw.WriteLine(dataline);
            }
        }


    }

    private DataTable createTemplate(List<string> lines)
    {

        List<string> headers = new List<string>();
        dataTable = new DataTable();
        if (lines.Count > 0)
        {
            string[] argHeaders = null;
            for (int i = 0; i < lines.Count; i++)
            {
                if (i > 0)
                {
                    DataRow newRow = dataTable.NewRow();
                    // others add to rows
                    string[] argLines = lines[i].Split(seprateChar);
                    for (int b = 0; b < argLines.Length; b++)
                    {
                        newRow[b] = argLines[b];
                    }
                    dataTable.Rows.Add(newRow);

                }
                else
                {
                    // header add to columns
                    argHeaders = lines[0].Split(seprateChar);
                    foreach (string c in argHeaders)
                    {
                        DataColumn column = new DataColumn(c, typeof(string));
                        dataTable.Columns.Add(column);
                    }
                }

            }

        }
        return dataTable;
    }

You can read and write csv file..
This may be helpful for you.

pass split char to this parameter "serparationChar"

Example : -

    private DataTable dataTable = null;
    private bool IsHeader = true;
    private string headerLine = string.Empty;
    private List<string> AllLines = new List<string>();
    private StringBuilder sb = new StringBuilder();
    private char seprateChar = ',';


    public DataTable ReadCSV(string path, bool IsReadHeader, char serparationChar)
    {
        seprateChar = serparationChar;
        IsHeader = IsReadHeader;
        using (StreamReader sr = new StreamReader(path,Encoding.Default))
        {
            while (!sr.EndOfStream)
            {
              AllLines.Add( sr.ReadLine());
            }
            createTemplate(AllLines);
        }

        return dataTable;
    }
    public void WriteCSV(string path,DataTable dtable,char serparationChar)
    {
        AllLines = new List<string>();
        seprateChar = serparationChar;
        List<string> StableHeadrs = new List<string>();
        int colCount = 0;
        using (StreamWriter sw = new StreamWriter(path))
        {
            foreach (DataColumn col in dtable.Columns)
            {
                sb.Append(col.ColumnName);
                if(dataTable.Columns.Count-1 > colCount)
                sb.Append(seprateChar);
                colCount++;
            }
            AllLines.Add(sb.ToString());

            for (int i = 0; i < dtable.Rows.Count; i++)
            {
                sb.Clear();
                for (int j = 0; j < dtable.Columns.Count; j++)
                {
                    sb.Append(Convert.ToString(dtable.Rows[i][j]));
                    if (dataTable.Columns.Count - 1 > j)
                    sb.Append(seprateChar);
                }
                AllLines.Add(sb.ToString());
            }

            foreach (string dataline in AllLines)
            {
                sw.WriteLine(dataline);
            }
        }


    }

    private DataTable createTemplate(List<string> lines)
    {

        List<string> headers = new List<string>();
        dataTable = new DataTable();
        if (lines.Count > 0)
        {
            string[] argHeaders = null;
            for (int i = 0; i < lines.Count; i++)
            {
                if (i > 0)
                {
                    DataRow newRow = dataTable.NewRow();
                    // others add to rows
                    string[] argLines = lines[i].Split(seprateChar);
                    for (int b = 0; b < argLines.Length; b++)
                    {
                        newRow[b] = argLines[b];
                    }
                    dataTable.Rows.Add(newRow);

                }
                else
                {
                    // header add to columns
                    argHeaders = lines[0].Split(seprateChar);
                    foreach (string c in argHeaders)
                    {
                        DataColumn column = new DataColumn(c, typeof(string));
                        dataTable.Columns.Add(column);
                    }
                }

            }

        }
        return dataTable;
    }
〆凄凉。 2024-09-14 07:44:19

我找到了最佳解决方案

http://www. codeproject.com/Articles/415732/Reading-and-Writing-CSV-Files-in-Csharp

只是我不得不重写

void ReadTest()
{
    // Read sample data from CSV file
    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();

            row = new CsvRow(); //this line added
        }
    }
}

I have found best solution

http://www.codeproject.com/Articles/415732/Reading-and-Writing-CSV-Files-in-Csharp

Just I had to re-write

void ReadTest()
{
    // Read sample data from CSV file
    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();

            row = new CsvRow(); //this line added
        }
    }
}
栀子花开つ 2024-09-14 07:44:19

好吧,还有另一个库 Cinchoo ETL - 一个开源库,用于读取和写入 CSV文件。

读取 CSV 文件的几种方法

Id, Name
1, Tom
2, Mark

这是使用此库读取它的方法

using (var reader = new ChoCSVReader("emp.csv").WithFirstLineHeader())
{
   foreach (dynamic item in reader)
   {
      Console.WriteLine(item.Id);
      Console.WriteLine(item.Name);
   }
}

如果您定义了 POCO 对象以与 CSV 文件匹配,如下所示

public class Employee
{
   public int Id { get; set; }
   public string Name { get; set; }
}

您可以使用此 POCO 类解析同一文件,如下所示

using (var reader = new ChoCSVReader<Employee>("emp.csv").WithFirstLineHeader())
{
   foreach (var item in reader)
   {
      Console.WriteLine(item.Id);
      Console.WriteLine(item.Name);
   }
}

请查看以下文章CodeProject 了解如何使用它。

免责声明:我是这个库的作者

Well, there is another library Cinchoo ETL - an open source one, for reading and writing CSV files.

Couple of ways you can read CSV files

Id, Name
1, Tom
2, Mark

This is how you can use this library to read it

using (var reader = new ChoCSVReader("emp.csv").WithFirstLineHeader())
{
   foreach (dynamic item in reader)
   {
      Console.WriteLine(item.Id);
      Console.WriteLine(item.Name);
   }
}

If you have POCO object defined to match up with CSV file like below

public class Employee
{
   public int Id { get; set; }
   public string Name { get; set; }
}

You can parse the same file using this POCO class as below

using (var reader = new ChoCSVReader<Employee>("emp.csv").WithFirstLineHeader())
{
   foreach (var item in reader)
   {
      Console.WriteLine(item.Id);
      Console.WriteLine(item.Name);
   }
}

Please check out articles at CodeProject on how to use it.

Disclaimer: I'm the author of this library

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文