Erstellen Sie eine TXT-Datei, wenn diese nicht vorhanden ist und eine neue Zeile angehängt wird


161

Ich möchte eine TXT-Datei erstellen und in diese schreiben. Wenn die Datei bereits vorhanden ist, möchte ich nur noch einige Zeilen anhängen:

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

Aber die erste Zeile scheint immer überschrieben zu werden ... wie kann ich vermeiden, in derselben Zeile zu schreiben (ich verwende dies in einer Schleife)?

Ich weiß, dass es eine ziemlich einfache Sache ist, aber ich habe die WriteLineMethode noch nie benutzt . Ich bin völlig neu in C #.


3
Beachten Sie, dass fast alle Antworten hier falsch sind und den Rennbedingungen unterliegen . Denken Sie daran: Das Muster if (file exists) { open file }ist fast immer in allen Programmiersprachen falsch! Für .NET besteht die Lösung darin, File.Open(path, FileMode.Append, FileAccess.ReadWrite)mit entsprechenden Flags zu verwenden.
ComFreek

"Ein FileMode-Wert, der angibt, ob eine Datei erstellt wird, wenn keine vorhanden ist, und bestimmt, ob der Inhalt vorhandener Dateien beibehalten oder überschrieben wird." Das Gleiche wird hier von .net anstelle des manuellen Ansatzes gemacht. Hier ist es also nicht falsch, es ist der gleiche Vorgang, der manuell durchgeführt wird. Sie können sagen, ineffizient, aber falsch zu sagen zählt nicht.
Berker Yüceer

Der Unterschied besteht darin, dass File.Openintern an eine WinAPI-Funktion delegiert wird (siehe nächster Kommentar), um hoffentlich die Rennbedingung zu verhindern. Die meisten Lösungen hier tun dies nicht und unterliegen offensichtlich den Rennbedingungen.
ComFreek

1
Die Existenzprüfung wird jedoch von FileMode bestimmt. Hier anhängen. Sie führt zu einer Existenzprüfung und erstellt dann eine Datei mit CreateFileA. Immer noch ein bisschen extrem falsch sagen, aber man kann sagen, ineffizient. Wir sollten auch nicht vergessen, dass die Existenzprüfung nicht nur für den Schreib- / Lesezugriff verwendet werden darf, sondern auch für andere Zwecke. Für Neueinsteiger ist dieses Thema hilfreich, um zu verstehen, wie es funktioniert. Wenn Sie jedoch eine Antwort hinzufügen können, die alle Definitionen enthält, die Sie hier geschrieben haben, und den Grund, warum es besser ist, würde dies als Antwort sehr hilfreich sein und wird wahrscheinlich als richtig ausgewählt.
Berker Yüceer

1
@ComFreek Ich stimme voll und ganz zu, dass Sie eine vollständige Antwort darüber schreiben sollten, um es klar zu erklären. Kommentare sind nicht zur Beantwortung gedacht, und ich bin aufrichtig neugierig auf diese Rennbedingungen und darauf, wie Sie sie lösen möchten.
Matthieu Foltzer

Antworten:


167

Verwenden Sie den richtigen Konstruktor :

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

11
Erste Antwort, einfachste Antwort, nützlichste Antwort für mich lol. Als ich es mir ansah, sagte ich: Huh? Nur ", wahr" hinzuzufügen ist genug? Wie kommt es, dass ich das vorher nicht sehe? Verdammt ... Ich fühlte mich total dumm, danke. Ich schätze diese guten Antworten wirklich sehr.
Berker Yüceer

7
Hinweis: Wenn die Datei nicht vorhanden ist, erstellt dieser Konstruktor eine neue Datei.
Abou-Emish

1
wickle ich in eine Verwendung (siehe Antwort unten).
David Thielen

1
Schließen ist überflüssig, wenn Sie verwenden
Michael Freidgeim

2
-1 Dies unterliegt den Rennbedingungen und kann zu falschem Verhalten führen! Vielleicht verwenden File.Open(path, FileMode.Append, FileAccess.ReadWrite)und überprüfen Sie lieber die Dateigröße über diesen zurückgegebenen Stream.
ComFreek

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

Siehe auch File.AppendAllText (). AppendAllLines fügt jeder Zeile eine neue Zeile hinzu, ohne sie selbst dort einfügen zu müssen.

Beide Methoden erstellen die Datei, wenn sie nicht vorhanden ist, sodass Sie dies nicht tun müssen.


3
Ich denke, dies ist angemessener für das, was der Benutzer gefragt hat. Es hört sich so an, als gäbe es zwei Probleme. 1 ist, dass der Text überschrieben wird - dies liegt daran, dass WriteLine die Datei überschreibt. In diesem Fall ist File.AppendAllText besser geeignet. und 2) - die Frage, wie ich meine Datei erstellen und wissen kann, dass ich sie anhänge. Es ist gut zu wissen, dass File.AppendAllText die Datei erstellt, das war meine Frage. StreamWriter ist nicht immer geeignet, es hängt davon ab, wofür diese Anwendung verwendet wird. In beiden Fällen hat mir das geholfen. +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!");
   }
}

Ich habe auch das gleiche Problem und finde dieses Poster, aber die Lösungen hier lösen mein Problem nicht. Also verwende ich einige Lösungsstücke und füge einfach Dispose () hinzu. Mein Ziel ist nicht das Kopieren und Einfügen.
Aek

1
Ich schlage nicht vor, dass es so war; Ich sage, ohne dies in Ihre Antwort aufzunehmen, wird das Originalplakat nicht wissen, warum Sie die von Ihnen vorgenommenen Änderungen vorgenommen haben oder was sie bewirken sollen. Geben Sie beim Posten immer alle relevanten Informationen an, damit die Leute wissen, was Sie tun. :)
DiMono

1
Dies funktioniert, weil es keinen Fehler gibt, der besagt, dass Sie nicht in die neu erstellte Datei schreiben können, weil sie von einem anderen Prozess verwendet wird. Die .Dispose () ist der Schlüssel. Ich danke dir sehr!
GenXisT

Damit wird in keiner Weise die Frage beantwortet, bei der es darum geht, die vorhandenen Inhalte zu erhalten.
Ben Voigt

Es macht keinen Sinn, Close()von einer usingAnweisung aus aufzurufen , da alle Ressourcen geschlossen werden, bevor sie automatisch entsorgt werden.
Sheridan

21

Sie müssen nicht überprüfen, ob die Datei vorhanden ist, da StreamWriter dies für Sie erledigt. Wenn Sie es im Append-Modus öffnen, wird die Datei erstellt, wenn sie nicht vorhanden ist. Dann werden Sie immer anhängen und niemals überschreiben. Ihre erste Prüfung ist also überflüssig.

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

1
Ich habe versucht, die Logik der akzeptierten Antwort zu erarbeiten. Ich wusste, dass ich dies zuvor in einer Zeile getan hatte, konnte mich aber nicht an die genaue Syntax erinnern. Danke dir.
Morvael

14

File.AppendAllText fügt einer Datei eine Zeichenfolge hinzu. Es wird auch eine Textdatei erstellt, wenn die Datei nicht vorhanden ist. Wenn Sie keine Inhalte lesen müssen, ist dies sehr effizient. Der Anwendungsfall ist die Protokollierung.

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

Dies ist genau das, was ich brauchte, aber wie kann ich den neuen Inhalt in einer neuen Zeile beginnen lassen? Ich verwende CSV-Dateien.
NiallUK

Ich denke, es gibt keine einfache Lösung. Ich würde Ihnen empfehlen, diesen Beitrag zu lesen. stackoverflow.com/questions/1343044/…
R.Cha


3

Wenn Sie StreamWriter starten, wird der Text überschrieben, der zuvor vorhanden war. Sie können die Eigenschaft append wie folgt verwenden:

TextWriter t = new StreamWriter(path, true);

3
 else if (File.Exists(path)) 
{ 
  using (StreamWriter w = File.AppendText(path))
        {
            w.WriteLine("The next line!"); 
            w.Close();
        }
 } 

1
Wenn Sie den Block "using" haben, ist w.Close redundant. Entsorgen Sie am Ende der Verwendung des Blocks das gleiche.
Michael Freidgeim

-1 Dies unterliegt den Rennbedingungen und kann zu falschem Verhalten führen! Vielleicht verwenden File.Open(path, FileMode.Append, FileAccess.ReadWrite)und überprüfen Sie lieber die Dateigröße über diesen zurückgegebenen Stream.
ComFreek


2

Versuche dies.

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!");
    }
}

Redudant File.AppendText(path), und damit keine Notwendigkeit zu überprüfen File.Exists(path). Und If (not A) Else If (A)ist ein komisches Wenn / Sonst. Grundsätzlich gibt es in dieser Frage nichts Gutes, keinen Erklärungscode, der eine redundante Version einer anderen Antwort ist.
xdtTransform

-1 Dies unterliegt den Rennbedingungen und kann zu falschem Verhalten führen! Vielleicht verwenden File.Open(path, FileMode.Append, FileAccess.ReadWrite)und überprüfen Sie lieber die Dateigröße über diesen zurückgegebenen Stream.
ComFreek

2

Sie können einfach die File.AppendAllText () -Methode verwenden, um Ihr Problem zu lösen. Diese Methode kümmert sich um die Dateierstellung, falls nicht verfügbar, und öffnet und schließt die Datei.

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

1

In der Microsoft-Dokumentation können Sie Dateien erstellen, falls diese nicht vorhanden sind, und sie in einem einzigen Aufruf anhängen. File.AppendAllText-Methode (String, String)

.NET Framework (aktuelle Version) Andere Versionen

Öffnet eine Datei, hängt die angegebene Zeichenfolge an die Datei an und schließt die Datei. Wenn die Datei nicht vorhanden ist, erstellt diese Methode eine Datei, schreibt die angegebene Zeichenfolge in die Datei und schließt die Datei. Namespace: System.IO Assembly: mscorlib (in mscorlib.dll)

Syntax C # C ++ F # VB public static void AppendAllText (Zeichenfolgenpfad, Zeichenfolgeninhalt) Parameterpfad Typ: System.String Die Datei, an die die angegebene Zeichenfolge angehängt werden soll. Inhaltstyp: System.String Die Zeichenfolge, die an die Datei angehängt werden soll.

AppendAllText


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

Im Allgemeinen sind Antworten viel hilfreicher, wenn sie eine Erklärung enthalten, was der Code tun soll und warum dies das Problem löst, ohne andere einzuführen.
Tim Diekmann
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.