2013-06-24 26 views
6

Znalazłem ten kod na stackoverflow, aby usunąć pierwszą i ostatnią linię z pliku tekstowego.Jak usunąć pierwszą i ostatnią linię z pliku tekstowego C#?

Ale nie rozumiem, jak połączyć ten kod w jeden, aby usunąć pierwszy i ostatni numer z jednego pliku?

Próbowałem używać streamreadera do odczytu pliku, a następnie pomiń pierwszą i ostatnią linię, a następnie streamwriter, aby napisać nowy plik, ale nie udało mi się uzyskać właściwej struktury.

Aby usunąć pierwszy wiersz.

var lines = System.IO.File.ReadAllLines("test.txt"); 
System.IO.File.WriteAllLines("test.txt", lines.Skip(1).ToArray()); 

usunięcie ostatniego wiersza.

var lines = System.IO.File.ReadAllLines("..."); 
System.IO.File.WriteAllLines("...", lines.Take(lines.Length - 1).ToArray()); 

Odpowiedz

20

Można łańcucha metod Skip i Take. Pamiętaj, aby odjąć odpowiednią liczbę linii w metodzie Take. Im więcej przeskoczysz na początku, tym mniej linii pozostanie.

var filename = "test.txt"; 
var lines = System.IO.File.ReadAllLines(filename); 
System.IO.File.WriteAllLines(
    filename, 
    lines.Skip(1).Take(lines.Length - 2) 
); 
1

Oto inne podejście, które wykorzystuje ArraySegment<string> zamiast:

var lines = File.ReadAllLines("test.txt"); 
File.WriteAllLines("test.txt", new ArraySegment<string>(lines, 1, lines.Length-2)); 
4

Chociaż prawdopodobnie nie jest to główny problem w tym przypadku, dotychczasowe odpowiedzi opierają się na czytanie całą zawartość pliku do pamięci jako pierwszy. W przypadku małych plików jest to prawdopodobnie w porządku, ale jeśli pracujesz z bardzo dużymi plikami, może to okazać się zbyt wygórowane.

Jest dość trywialne stworzyć SkipLast odpowiednik istniejącej metody Skip Linq:

public static class SkipLastExtension 
{ 
    public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int count) 
    { 
     var queue = new Queue<T>(); 
     foreach (var item in source) 
     { 
      queue.Enqueue(item); 
      if (queue.Count > count) 
      { 
       yield return queue.Dequeue(); 
      } 
     } 
    } 
} 

Gdybyśmy również zdefiniować metodę, która pozwala nam wyliczyć na każdej linii pliku bez wstępnego buforowania całość pliku (za: https://stackoverflow.com/a/1271236/381588):

static IEnumerable<string> ReadFrom(string filename) 
{ 
    using (var reader = File.OpenText(filename)) 
    { 
     string line; 
     while ((line = reader.ReadLine()) != null) 
     { 
      yield return line; 
     } 
    } 
} 

Wtedy możemy użyć następujących następującym jedną wkładką napisać nowy plik zawierający wszystkie linie od oryginalnego pliku, z wyjątkiem pierwszego i ostatniego:

File.WriteAllLines("output.txt", ReadFrom("input.txt").Skip(1).SkipLast(1)); 

Jest to niewątpliwie (znacznie) więcej kodu niż inne odpowiedzi, które zostały już zamieszczone tutaj, ale powinien działać na plikach zasadniczo dowolnej wielkości, (jak również dostarczenie kodu dla potencjalnie użyteczną metodą SkipLast przedłużacza).

+2

+1 za myślenie o krytycznym błędzie * przed * zgłoszeniem przez klienta ;-) –

Powiązane problemy