Utwórz plik .txt, jeśli nie istnieje, a jeśli tak, dołącz nowy wiersz


161

Chciałbym stworzyć plik .txt i napisać do niego, a jeśli plik już istnieje, chcę tylko dodać kilka wierszy:

string path = @"E:\AppServ\Example.txt";
if (!File.Exists(path))
{
    File.Create(path);
    TextWriter tw = new StreamWriter(path);
    tw.WriteLine("The very first line!");
    tw.Close();
}
else if (File.Exists(path))
{
    TextWriter tw = new StreamWriter(path);
    tw.WriteLine("The next line!");
    tw.Close(); 
}

Ale wydaje się, że pierwsza linia zawsze jest nadpisywana ... jak mogę uniknąć pisania w tej samej linii (używam tego w pętli)?

Wiem, że to dość prosta rzecz, ale nigdy wcześniej nie korzystałem z tej WriteLinemetody. Jestem zupełnie nowy w C #.


3
Uważaj, prawie wszystkie odpowiedzi tutaj są błędne i zależą od warunków wyścigu . Pamiętaj: wzorzec if (file exists) { open file }jest prawie zawsze błędny we wszystkich językach programowania! W przypadku platformy .NET rozwiązaniem jest użycie File.Open(path, FileMode.Append, FileAccess.ReadWrite)odpowiednich flag.
ComFreek

„Wartość FileMode, która określa, czy plik jest tworzony, jeśli taki nie istnieje, i określa, czy zawartość istniejących plików jest zachowywana, czy nadpisywana”. tak samo robi .net zamiast ręcznego podejścia tutaj. Więc nie jest źle, jest to ten sam proces, który jest wykonywany ręcznie. Możesz powiedzieć, że nieefektywne, ale mówienie źle się nie liczy.
Berker Yüceer

Różnica polega na tym, że File.Openwewnętrznie deleguje do funkcji WinAPI (patrz następny komentarz), miejmy nadzieję, że zapobiega wyścigowi. Większość rozwiązań tutaj tego nie robi i są one oczywiście uzależnione od warunków wyścigu.
ComFreek

1
Jednak sprawdzenie istnienia jest określane przez FileMode.Append tutaj .. i kieruje do sprawdzenia istnienia, a następnie tworzy plik z CreateFileA. Nadal mówisz źle, trochę ekstremalnie, ale możesz powiedzieć, że nieskuteczne. Nie powinniśmy również zapominać, że sprawdzenie istnienia nie może być używane tylko do zapisu / odczytu, może być również używane przez inne sprawy, więc dla początkujących ten temat jest przydatny do zrozumienia, jak to działa. Jeśli jednak możesz dodać odpowiedź zawierającą wszystkie definicje, które tutaj napisałeś i powód, dla którego jest lepiej, to bardzo by pomogło jako odpowiedź i prawdopodobnie zostanie wybrane jako poprawne.
Berker Yüceer

1
@ComFreek Zdecydowanie zgadzam się, że powinieneś napisać pełną odpowiedź na ten temat, aby jasno to wyjaśnić. Komentarze nie służą do odpowiadania na nie i jestem szczerze ciekawa warunków wyścigu i tego, jak proponujesz je rozwiązać.
Matthieu Foltzer

Odpowiedzi:


167

Użyj odpowiedniego konstruktora :

else if (File.Exists(path))
{
    using(var tw = new StreamWriter(path, true))
    {
        tw.WriteLine("The next line!");
    }
}

11
Pierwsza odpowiedź, najprostsza odpowiedź, najbardziej przydatna odpowiedź dla mnie lol. Kiedy na to spojrzałem, pomyślałem: Hę? wystarczy dodać „prawda”? Dlaczego nie widzę tego wcześniej? Cholera ... Czułem się jak totalnie głupi dzięki. Naprawdę doceniam te dobre odpowiedzi.
Berker Yüceer

7
wskazówka: Jeśli plik nie istnieje, ten konstruktor tworzy nowy plik.
Abou-Emish

1
zawiń w użycie (patrz odpowiedź poniżej).
David Thielen

1
Zamknięcie jest zbędne, jeśli używasz
Michael Freidgeim

2
-1 Zależy to od warunków wyścigu i może powodować niewłaściwe zachowanie! Może raczej użyj File.Open(path, FileMode.Append, FileAccess.ReadWrite)i sprawdź rozmiar pliku przez ten zwrócony strumień.
ComFreek

57
string path = @"E:\AppServ\Example.txt";
File.AppendAllLines(path, new [] { "The very first line!" });

Zobacz także File.AppendAllText (). AppendAllLines doda nową linię do każdej linii bez konieczności jej samodzielnego umieszczania.

Obie metody utworzą plik, jeśli nie istnieje, więc nie musisz.


3
Myślę, że jest to bardziej odpowiednie dla tego, o co prosił użytkownik. Wygląda na to, że są 2 problemy. 1 oznacza, że ​​tekst jest nadpisywany - dzieje się tak, ponieważ WriteLine nadpisuje plik. W takim przypadku bardziej odpowiedni jest plik File.AppendAllText. i 2) - pytanie jak mogę stworzyć swój plik i wiedzieć, że do niego doklejam. Dobrze wiedzieć, że File.AppendAllText tworzy plik, to było moje pytanie. StreamWriter nie zawsze jest odpowiedni, zależy to od tego, do czego ta aplikacja jest używana. W każdym razie to mi pomogło. +1
Devin C,

42
string path=@"E:\AppServ\Example.txt";

if(!File.Exists(path))
{
   File.Create(path).Dispose();

   using( TextWriter tw = new StreamWriter(path))
   {
      tw.WriteLine("The very first line!");
   }

}    
else if (File.Exists(path))
{
   using(TextWriter tw = new StreamWriter(path))
   {
      tw.WriteLine("The next line!");
   }
}

Ja też mam ten sam problem i znalazłem ten plakat, ale rozwiązania tutaj nie rozwiązują mojego problemu. Więc używam kilku fragmentów rozwiązania i po prostu dodaję Dispose () .Moim celem nie jest kopiowanie i wklejanie.
Aek,

1
Nie sugeruję, że tak; Mówię, że bez uwzględnienia tego w Twojej odpowiedzi oryginalny plakat nie będzie wiedział, dlaczego wprowadziłeś zmiany, które wprowadziłeś, ani co mają osiągnąć. Zawsze dołączaj wszystkie istotne informacje, kiedy publikujesz, aby ludzie wiedzieli o wszystkim, co robisz. :)
DiMono,

1
Działa to, ponieważ nie wyświetla błędu informującego, że nie możesz pisać do nowo utworzonego pliku, ponieważ jest używany przez inny proces. Kluczem jest .Dispose (). Dziękuję bardzo!
GenXisT

To w żaden sposób nie rozwiązuje problemu, który polega na zachowaniu istniejącej treści.
Ben Voigt

Nie ma sensu wywoływać Close()z usinginstrukcji, ponieważ wszystkie zasoby zostaną zamknięte przed automatycznym usunięciem.
Sheridan,

21

W rzeczywistości nie musisz sprawdzać, czy plik istnieje, ponieważ StreamWriter zrobi to za Ciebie. Jeśli otworzysz go w trybie dopisywania, plik zostanie utworzony, jeśli nie istnieje, wtedy zawsze będziesz dodawać i nigdy nie nadpisywać. Więc twoja wstępna kontrola jest zbędna.

TextWriter tw = new StreamWriter(path, true);
tw.WriteLine("The next line!");
tw.Close(); 

1
Próbowałem wypracować logikę zaakceptowanej odpowiedzi, wiedziałem, że zrobiłem to wcześniej w jednej linii, ale nie pamiętałem dokładnej składni. Dziękuję Ci.
Morvael

14

File.AppendAllText dodaje ciąg do pliku. Tworzy również plik tekstowy, jeśli plik nie istnieje. Jeśli nie musisz czytać treści, jest to bardzo wydajne. Przypadek użycia to rejestrowanie.

File.AppendAllText("C:\\log.txt", "hello world\n");

To jest właśnie to, czego potrzebowałem, ale jak mogę sprawić, aby nowa zawartość zaczęła się w nowej linii? Używam plików CSV.
NiallUK

Chyba nie ma prostego rozwiązania. Proponuję sprawdzić ten wpis. stackoverflow.com/questions/1343044/…
R.Cha


3

Po uruchomieniu StreamWriter zastępuje tekst, który był tam wcześniej. Możesz użyć właściwości append w następujący sposób:

TextWriter t = new StreamWriter(path, true);



2

Spróbuj tego.

string path = @"E:\AppServ\Example.txt";
if (!File.Exists(path))
{
    using (var txtFile = File.AppendText(path))
    {
        txtFile.WriteLine("The very first line!");
    }
}
else if (File.Exists(path))
{     
    using (var txtFile = File.AppendText(path))
    {
        txtFile.WriteLine("The next line!");
    }
}

Nadmiarowy File.AppendText(path), a dzięki temu nie trzeba go sprawdzać File.Exists(path). I If (not A) Else If (A)to dziwne Jeśli / Inaczej. Zasadniczo nie ma nic dobrego w tym pytaniu, nie ma kodu wyjaśniającego, który byłby redudatywną wersją innej odpowiedzi.
xdtTransform

-1 Zależy to od warunków wyścigu i może powodować niewłaściwe zachowanie! Może raczej użyj File.Open(path, FileMode.Append, FileAccess.ReadWrite)i sprawdź rozmiar pliku przez ten zwrócony strumień.
ComFreek

2

Możesz po prostu użyć metody File.AppendAllText (), aby rozwiązać problem. Ta metoda zajmie się tworzeniem pliku, jeśli nie jest dostępna, otwieraniem i zamykaniem pliku.

var outputPath = @"E:\Example.txt";
var data = "Example Data";
File.AppendAllText(outputPath, data);

1

Z dokumentacji firmy Microsoft można utworzyć plik, jeśli nie istnieje, i dołączyć do niego w jednym wywołaniu Metoda File.AppendAllText (String, String)

.NET Framework (aktualna wersja) Inne wersje

Otwiera plik, dołącza określony ciąg do pliku, a następnie zamyka plik. Jeśli plik nie istnieje, ta metoda tworzy plik, zapisuje określony ciąg do pliku, a następnie zamyka plik. Przestrzeń nazw: System.IO Assembly: mscorlib (w mscorlib.dll)

Składnia C # C ++ F # VB public static void AppendAllText (ścieżka ciągu, zawartość ciągu) Parametry ścieżka Typ: System.String Plik, do którego ma zostać dołączony określony ciąg. zawartość Typ: System.String Ciąg do dołączenia do pliku.

AppendAllText


1
using(var tw = new StreamWriter(path, File.Exists(path)))
{
    tw.WriteLine(message);
}

Ogólnie odpowiedzi są znacznie bardziej pomocne, jeśli zawierają wyjaśnienie, do czego służy kod i dlaczego to rozwiązuje problem bez wprowadzania innych.
Tim Diekmann
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.