c# - 操作现有的 CSV 文件,同时保持列顺序。 (CsvReader/CsvWriter)

标签 c#

我需要通过以下操作操作现有的 CSV 文件:

  1. 从现有 CSV 文件中读取 -> 然后向其中追加新行。 我有以下代码,该代码在第三行中令人窒息 - 因为该文件已被第一行中的代码使用。而且我不知道如何正确读取它,然后向其附加新行。
public bool Save(Customer customer)
{
    using (StreamReader input = File.OpenText("DataStoreOut.csv"))
    using (CsvReader csvReader = new CsvReader(input))
    using (StreamWriter output = File.CreateText("DataStoreOut.csv"))
    using (var csvWriter = new CsvWriter(output))
    {
        IEnumerable<Customer> records = csvReader.GetRecords<Customer>();

        List<Customer> customerList = new List<Customer>();
        customerList.Add(customer);

        csvWriter.WriteHeader<Customer>();
        csvWriter.NextRecord();

        foreach (var array in customerList)
        {
            csvWriter.WriteRecord(records.Append(array));
        }
    }
}
  • CSV 文件中的每一行都包含一个 customer.CustomerId(唯一且只读)。如何只读取具有特定 customerId 的行,然后更新其中的任何值。
  • 最佳答案

    如果要将记录追加到文件中,最好的方法是读取项目,将新记录添加到集合中,然后将所有内容写回。

    public static void Append(Customer customer, string file)
    {
        List<Customer> records = null;
        using (var reader = new StreamReader(file))
        {
            using (var csv = new CsvReader(reader))
            {
                records = csv.GetRecords<Customer>().ToList();
            }
        }
        records.Add(customer);
    
        using (var writer = new StreamWriter(file))
        {
            using (var csv = new CsvWriter(writer))
            {
                csv.WriteRecords(records);
            }
        }
    }
    

    正如 @Dour High Arch 提到的,为了绝对安全,您可能需要采取额外的步骤使用临时文件,以防出现问题。

    如果您想更新而不是追加,则必须查找指定的记录,如果存在则更新它。

    public static void Update(Customer customer, string file)
    {
        List<Customer> records = null;
        using (var reader = new StreamReader(file))
        {
            using (var csv = new CsvReader(reader))
            {
                records = csv.GetRecords<Customer>().ToList();
            }
        }
        var index = records.FindIndex(x => x.ID == customer.ID);
        if (index >= 0)
        {
            records[index] = customer;
            using (var writer = new StreamWriter(file))
            {
                using (var csv = new CsvWriter(writer))
                {
                    csv.WriteRecords(records);
                }
            }
        }
    }
    

    同样,建议写入临时文件。


    更新

    实际上,如果您不想替换文件,还有一种更好的附加方法。当实例化StreamWriter时您可以使用append=true来做到这一点。在这种情况下,它将附加到文件末尾。 需要注意的是,如果 EOF标记不是在新行,而是在最后一个记录的最后一个字段,这会将记录附加到最后一个字段的末尾,从而弄乱您的列。作为解决方法,我添加了 writer.WriteLine();在使用 CSVHelper 之前类的作家。

    public static void Append2(Customer customer, string file)
    {
        using (var writer = new StreamWriter(file, true))
        {
            writer.WriteLine();
            using (var csv = new CsvWriter(writer))
            {
                csv.WriteRecord(customer);
            }
        }
    }
    

    如果文件位于新行中,那么这将添加一个空行。这可以通过在读取文件时忽略空行来解决。

    关于c# - 操作现有的 CSV 文件,同时保持列顺序。 (CsvReader/CsvWriter),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58984212/

    相关文章:

    c# - 在 .NET Core 2 中创建 HttpClient 的最佳实践

    c# - MVVM 的通用接口(interface)

    c# - 找不到“WindowsFormsHost”

    c# - 在 WCF 中实例化服务对象的默认行为是什么?

    c# - 为什么使用 GMAIL : text/html; is missing when use MailItem in Outlook plugin, GMAIL.COM 的 SMTP 服务器对 header 内容类型 : SMTP. 进行编码?

    c# - 等效于 (VB6) IsMissing 在 C# 中?

    c# - Windows shell 扩展 : context menu when more than 16 files are selected

    c# - 动态添加点击事件

    c# - 为什么数组实现 IList?

    c# - 在 Combobox 中按 Enter 键清除文本