C# - 如果行不存在则写入行

时间:2016-12-30 18:56:19

标签: c# csv readfile writefile

如果CSV文件中不存在确切的字符串,我正在尝试将CS​​V文件中的一行写为字符串。当我不检查线是否存在时,我的代码对我来说很好。

我当前的代码如下所示,似乎无法正常工作。

string output = @"output.csv";
TextWriter tw = new StreamWriter(output);

foreach (var player in replay.Players.OrderByDescending(i => i.IsWinner))
{
    using (StreamReader sr = new StreamReader(output))
    {
        string contentsToRead = File.ReadAllText(output);
        string contentsToWrite = replay.ReplayBuild + "," + replay.Map;
        if (!contentsToRead.Contains(contentsToWrite))
            tw.WriteLine(contentsToWrite);
        sr.Close();
    }
}
tw.Close();

我对C#和编程一般都是新手。我正在处理的文件的主要工作不是我的。它最初来自https://github.com/barrett777/Heroes.ReplayParser

如果我注释掉StreamReader并且只使用Write行,那么它至少在我的理解下是完全有效的。

我非常感谢任何有关如何改进的帮助和提示。提前谢谢。

2 个答案:

答案 0 :(得分:1)

尝试阅读文件内容,然后再将其打开(new StreamWriter(output)行之前)。

答案 1 :(得分:0)

我建议使用File.ReadLines以及File.AppendAllLines。为了不更新文件 逐行(这可能很耗时)但一次性推荐 Linq

string output = @"output.csv";
...

// Hash set is effcient - O(N) - for testing if line exists or not  
HashSet<String> existingLines = new HashSet<String>(File
  .ReadLines(output));

//TODO: please, check this selection (I'm not sure in ReplayBuild and Map attributes) 
var toAppend = replay
  .Players
  .Select(player => new {
     toWrite = string.Join(",", player.ReplayBuild, player.Map),
     isWinner = player.IsWinner })
  .Where(item => existingLines.Contains(item.toWrite))
  .OrderByDescending(item => item.isWinner)
  .Select(item => item.toWrite)
  .ToList(); // since we're writing into the same file, we have to materialize

// Do we have anything to write?
if (toAppend.Any())
  File.AppendAllLines(output, toAppend);