2017-02-10 44 views
1

Недавно я столкнулся с проблемой, в которой я не смог найти решение, соответствующее моим потребностям. Поэтому я пытаюсь прочитать текстовый файл по строкам и проверить, является ли строка конкретной строкой. Если файл не содержит эту строку, он должен быть записан в файл. Это мой текущий подход к этому.Использование StreamReader & Writer в том же текстовом файле

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

Другой вариант, который не предлагается, заключается в том, чтобы открыть читатель на исходном файле, писатель в временном файле. Прочтите исходную запись в файл temp и добавьте недостающие строки, затем замените исходный файл на файл temp.