【问题标题】:Using StreamReader & Writer on same Textfile在同一个文本文件上使用 StreamReader 和 Writer
【发布时间】:2017-06-29 00:42:53
【问题描述】:

我最近遇到了一个我无法找到适合我需要的解决方案的问题。所以我试图逐行读取文本文件并检查该行是否为特定字符串。如果文件不包含该字符串,则应将其写入文件。这是我目前的做法。

int i = 0;
using (var sw = new StreamWriter(this.filePath))
{
    foreach (SimplePlaylist playlist in myPlaylists)
    {
        this.PlaylistTracks[i] = new List<PlaylistTrack>();
        this.PlaylistTracks[i] = GetPlaylistTracks(playlist.Owner.Id, playlist.Id);
        foreach (PlaylistTrack tr in this.PlaylistTracks[i])
        {
            string write = tr.Track.Name + " // " + string.Join(",", tr.Track.Artists.Select(source => source.Name)) + " // " + tr.Track.Album.Id;
            string line = "";
            bool found = false;
            using (var sr = new StreamReader(this.filePath))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    if (line.Equals(write))
                    {
                        found = true;
                        break;
                    }
                }
                sr.Close();
            }
            if (!found)
            {
                sw.WriteLine(write);
            }
        }
        i++;
    }
    sw.Close();
}

我已经阅读了同时读取和写入文件的问题,但我想知道是否有办法实现这一点。任何帮助表示赞赏!

【问题讨论】:

  • 先完成所有的阅读,创建一个你需要添加的行列表。然后把这些行写出来。阅读和写作必须一起完成有什么原因吗?
  • gunnerone,如果文件内容很大,这不是一个好方法。我想这首先是流媒体的目的。

标签: c# streamreader streamwriter


【解决方案1】:

请注意,您当前的方法效率非常低,需要您的代码从磁盘读取文件以搜索每个字符串。

您将无法像您尝试那样使用两个不同的流同时读取和写入同一个文件。以下是我在不了解的情况下建议的几种策略:

  1. 如果文件很小,将 while 文件加载到 List 中,然后关闭阅读器。然后您可以在列表中搜索每个字符串:

    if(!list.Any(write))
        // Write the string to the file  
    

    这将非常快,因为列表在内存中并且文件只读取一次(前提是它相当小 - 比如说

  2. 另一种方法是将缺失的字符串添加到列表中,一旦确定了所有缺失的字符串,关闭阅读器并使用编写器添加字符串。这仍然是低效的,因为您正在为每次查找读取整个文件(可能很大),所以

  3. 这种方法的一个改进是通读文件并检查每一行是否与您可能要添加的所有行。这意味着您只需读取一次文件并运行每行的播放列表集合,因为它在内存中,所以效率更高。假设您只有几行要检查 - 比如您正在添加的一些新歌曲,这将提高效率很多倍。

如果文件变得非常大,您可能需要某种索引查找方法。

【讨论】:

    【解决方案2】:

    另一个不建议的选项是打开原始文件的读取器,临时文件的写入器。从原始写入读取临时文件并添加缺少的行,然后将原始文件替换为临时文件。

    【讨论】:

      【解决方案3】:

      使用 FileStream 并将其用于 StreamReader 和 StreamWriter,这是添加或更改 textFile 行的示例:

      public static void ChangeOrAddLine(string filePath, string newLine, string oldLine = "")
      {
          using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
          using (StreamReader sr = new StreamReader(fs))
          using (StreamWriter sw = new StreamWriter(fs))
          {
              List<string> lines = sr.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
              fs.Position = 0;
              bool lineFound = false;
              if (oldLine != "")
                  for (int i = 0; i < lines.Count; i++)
                      if (lines[i] == oldLine)
                      {
                          lines[i] = newLine;
                          lineFound = true;
                          break;
                      }
              if (!lineFound)
                  lines.Add(newLine);
              sw.Write(string.Join("\r\n", lines));
              fs.SetLength(fs.Position);
          }
      }
      

      FileAccess.ReadWrite 打开文件进行读写

      FileShare.Read 让其他程序也可以读取文件

      【讨论】:

        猜你喜欢
        • 2019-02-26
        • 2013-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-09
        • 1970-01-01
        • 2015-10-27
        • 2012-02-22
        相关资源
        最近更新 更多