2017-02-10 30 views
1

我最近碰到一個問題,我無法找到一個解決方案,即適合我的需要使用的StreamReader與作家。所以我試圖逐行閱讀一個文本文件,並檢查該行是否是特定的字符串。如果文件不包含該字符串,則應將其寫入文件。這是我目前對此的讚賞。對同一文本文件

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(); 
} 

我已閱讀有關在同一時間讀取和寫入文件的問題,但我想知道是否有辦法實現這一點。任何幫助表示讚賞!

+0

如何做所有的閱讀第一,創造你需要添加行的列表。然後寫下這些線。閱讀和寫作必須一起完成嗎? – gunnerone

+0

gunnerone,如果文件內容很大,不是一個好方法。我想,這首先是流式傳輸的目的。 – Tilak

回答

1

使用一個FileStream,並用它來兩者的StreamReader和StreamWriter,這裏是添加或更改文本文件的行的例子:

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讓其他程序也可以讀取

1

請注意,您當前的方法效率非常低,需要您的代碼通過磁盤讀取文件以搜索每個字符串。

你不會是能夠讀取,並在同一時間有兩個不同的流像你試圖做寫入同一文件。這裏有幾個策略,我建議不知道更多:

  1. 如果該文件是小,加載而文件到列表中,然後關閉閱讀器。然後,您可以搜索列表中的每個字符串:

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

    這將是非常快的,因爲該列表是在內存中,該文件是隻讀一次(只要它是相當小 - 說< 5000線,雖然它也將在更大的文件上工作)。

  2. 另一種方法是缺失的字符串添加到列表,一旦你已經確定了所有缺少的字符串,關閉閱讀器和使用作家添加字符串。這仍然是效率低下的,因爲您正在通過查看整個文件(這可能很大),所以每個查找,所以

  3. 這種方法的改進是閱讀文件,並檢查每一行對所有行可能要添加。這意味着您只能讀取一次文件並遍歷每行的播放列表集合,因爲它位於內存中,因此效率會更高。假設你只有幾行你正在檢查 - 比如你添加的一些新歌曲,這將提高效率很多次。

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

1

不建議另一種方法是打開原始文件的讀者,作家上的臨時文件。從原始寫入讀取臨時文件並添加缺少的行,然後用臨時文件替換原始文件。