Dołącz wiersze do pliku przy użyciu StreamWriter

170

Chcę dołączyć wiersze do mojego pliku. Używam StreamWriter:

StreamWriter file2 = new StreamWriter(@"c:\file.txt");
file2.WriteLine(someString);
file2.Close();

Wynik mojego pliku powinien znajdować się kilka ciągów pod sobą, ale mam tylko jeden wiersz, który jest nadpisywany za każdym razem, gdy uruchamiam ten kod.

Czy istnieje sposób, aby StreamWriter dołączyć do istniejącego pliku?

Punkt orientacyjny
źródło
19
Nie zapomnij wyrzucić StreamWriter. usingBlok jest lepiej składnię tego.
TheCodeKing,
1
Dlatego też wolę nie przejmować się strumieniami podczas wykonywania bardzo szybkich aktualizacji pliku za pomocą File.AppendAllText - msdn.microsoft.com/en-us/library/ms143356.aspx
Chris
@TheCodeKing - Czy możesz mi pokazać kod, który to zrobi?
Steam
4
@blastousing (var stream = new StreamWriter(..)) { stream.WriteLine(..); }
TheCodeKing

Odpowiedzi:

279

Użyj tego zamiast tego:

new StreamWriter("c:\\file.txt", true);

Przy tym przeciążeniu konstruktora StreamWriter możesz wybrać, czy dołączysz plik, czy go zastąpisz.

C # 4 i nowsze oferują następującą składnię, która dla niektórych jest bardziej czytelna:

new StreamWriter("c:\\file.txt", append: true);
Øyvind Bråthen
źródło
145
 using (FileStream fs = new FileStream(fileName,FileMode.Append, FileAccess.Write))
 using (StreamWriter sw = new StreamWriter(fs))
 {
    sw.WriteLine(something);
 }
Andrey Taptunov
źródło
13

Zakładam, że wykonujesz cały powyższy kod za każdym razem, gdy zapisujesz coś do pliku. Za każdym razem, gdy strumień pliku jest otwierany, jego wskaźnik wyszukiwania jest umieszczany na początku, więc wszystkie zapisy kończą się nadpisywaniem tego, co było wcześniej.

Możesz rozwiązać problem na dwa sposoby: albo za pomocą wygodnego

file2 = new StreamWriter("c:/file.txt", true);

lub samodzielnie zmieniając położenie wskaźnika strumienia:

file2 = new StreamWriter("c:/file.txt");
file2.BaseStream.Seek(0, SeekOrigin.End);
Jon
źródło
co jeśli plik ma 10 MB i zaczynam pisać od pozycji 0, ale tylko 10 KB, jak mogę zapewnić, że plik zawiera tylko 10 KB danych, które właśnie zapisałem?
JobaDiniz
10

Spróbuj tego:

StreamWriter file2 = new StreamWriter(@"c:\file.txt", true);
file2.WriteLine(someString);
file2.Close();
Marco
źródło
7

Zastąp to:

StreamWriter file2 = new StreamWriter("c:/file.txt");

z tym:

StreamWriter file2 = new StreamWriter("c:/file.txt", true);

true wskazuje, że dołącza tekst.

Waqas
źródło
5

Inną opcją jest użycie System.IO.File.AppendText

Jest to równoważne z przeciążeniami StreamWriter podanymi przez innych.

Również File.AppendAllText może dać nieco łatwiejszy interfejs bez martwienia się o otwieranie i zamykanie strumienia. Chociaż może wtedy będziesz musiał martwić się wprowadzaniem własnych podziałów linii. :)

Chris
źródło
5

Właściwie tylko odpowiedź Jona (wrzesień 5 '11 o 9:37) z BaseStream.Seek zadziałała w moim przypadku. Dzięki Jon! Musiałem dołączyć wiersze do zarchiwizowanego pliku txt.

using (FileStream zipFS = new FileStream(@"c:\Temp\SFImport\test.zip",FileMode.OpenOrCreate))
{
    using (ZipArchive arch = new ZipArchive(zipFS,ZipArchiveMode.Update))
    {
        ZipArchiveEntry entry = arch.GetEntry("testfile.txt");
        if (entry == null)
        {
            entry = arch.CreateEntry("testfile.txt");
        }
        using (StreamWriter sw = new StreamWriter(entry.Open()))
        {
            sw.BaseStream.Seek(0,SeekOrigin.End);
            sw.WriteLine("text content");
        }
    }
}

źródło
3

Jeszcze prostszym sposobem jest File.AppendTextdodanie tekstu zakodowanego w UTF-8 do istniejącego pliku lub do nowego pliku, jeśli określony plik nie istnieje i zwracaSystem.IO.StreamWriter

using (System.IO.StreamWriter sw = System.IO.File.AppendText(logFilePath + "log.txt"))
{                                                
    sw.WriteLine("this is a log");
}
Vinod Srivastav
źródło
1

Zastąp tę linię:

StreamWriter sw = new StreamWriter("c:/file.txt");

z tym kodem:

StreamWriter sw = File.AppendText("c:/file.txt");

a następnie zapisz swoją linię do pliku tekstowego w ten sposób:

sw.WriteLine("text content");
Shahaf
źródło