Erstellen einer leeren Datei in C #

185

Was ist der einfachste / kanonischste Weg, um eine leere Datei in C # /. NET zu erstellen?

Der einfachste Weg, den ich bisher finden konnte, ist:

System.IO.File.WriteAllLines(filename, new string[0]);
Paul Hollingsworth
quelle

Antworten:

384

Mit just File.Create bleibt die Datei geöffnet, was wahrscheinlich nicht das ist, was Sie wollen.

Du könntest benutzen:

using (File.Create(filename)) ;

Das sieht etwas seltsam aus, wohlgemerkt. Sie könnten stattdessen geschweifte Klammern verwenden:

using (File.Create(filename)) {}

Oder rufen Sie einfach Disposedirekt an:

File.Create(filename).Dispose();

In beiden Fällen sollten Sie, wenn Sie dies an mehreren Stellen verwenden möchten, wahrscheinlich in Betracht ziehen, es in eine Hilfsmethode einzuschließen, z

public static void CreateEmptyFile(string filename)
{
    File.Create(filename).Dispose();
}

Beachten Sie, dass Aufruf Disposedirekt anstelle der Verwendung eines usingnicht wirklich viel Unterschied macht hier so weit wie ich kann sagen Aussage - den einzigen Weg , es könnte einen Unterschied machen, wenn der Faden zwischen dem Aufruf abgebrochen wurde File.Createzu und der Anruf Dispose. Wenn diese Racebedingung vorliegt, würde sie vermutlich auch in der usingVersion vorhanden sein, wenn der Thread am Ende der File.CreateMethode abgebrochen würde , kurz bevor der Wert zurückgegeben wurde ...

Jon Skeet
quelle
8
Komisch. Ich habe vor ungefähr 5 Minuten den gleichen Code geschrieben. Ich habe File.Create (Dateiname) .Close () gemacht; Gleicher
Unterschied
2
Mein Code wurde verwendet using (File.Create(filename)) ;, aber ich liebe die Einfachheit vonFile.Create(filename).Dispose();
Vadim
@BrianGenisio: Ich habe den gleichen Code auch vor ungefähr 5 Minuten gemacht! Ich habe nur gegoogelt, um zu sehen, wie andere Programmierer es gemacht haben. Jetzt benutze ich File.Create(filename).Dispose();statt.
Jack
1
@ user3791372: Gibt Close()auch die Ressourcen frei. Close()ruft einfach an Dispose- siehe github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/…
Jon Skeet
1
Es ist möglicherweise nicht offensichtlich, dass der Dateiinhalt überschrieben wird, wenn die Datei bereits vorhanden und nicht schreibgeschützt ist. Um dies zu vermeiden, verwenden Sieusing (new FileStream(filename, FileMode.CreateNew)) { }
Phil Haselden
34
File.WriteAllText("path", String.Empty);

oder

File.CreateText("path").Close();
knocte
quelle
2
Bei Verwendung der ersten Datei ist die Datei 3 Byte lang: der Codierungscode. Mit der Sekunde ist die Datei von 0 Byte (wirklich leer).
Fil
1
@Fil: Bist du sicher? Die Dokumentation sagt , dass die File.WriteAllText(string, string)Verwendungen "UTF-8 - Codierung ohne Byte-Order Mark (BOM)" . Wenn Sie immer noch einen sehen, wäre dies ein Fehler in WriteAllText oder seiner Dokumentation, die es wert ist, gemeldet zu werden.
Heinzi
Ich erinnere mich, dass ich es versucht habe. Vielleicht war es ein alter Fehler der vorherigen .Net-Version? Die Datei ist nicht leer, wenn ich explizit die Verwendung von UTF8-Codierung (oder Unicode oder etwas anderem) spezifiziere: <File.WriteAllText ("c: \ del.txt", String.Empty, System.Text.Encoding.UTF8);>
Fil
1
@Fil Encoding.UTF8gibt einen Encoder zurück, der das Byte Order Mark (BOM) ausgibt. Sie können new UTF8Encoding(false)einen UTF8-Encoder verwenden, der die Stückliste nicht ausgibt.
Daniel Crabtree
1
Ich weiß nicht, ob ich WriteAllTextmich in der vorherigen Version von .NET wirklich anders verhalte. Um ganz sicher zu gehen, überspringen Sie einfach den Codierungsteil und verwenden Sie ihn File.WriteAllBytes(path, new byte[] { });stattdessen.
Jürgen Steinblock
20
System.IO.File.Create(@"C:\Temp.txt");

Wie andere bereits betont haben, sollten Sie dieses Objekt entsorgen oder in eine leere using-Anweisung einschließen.

using (System.IO.File.Create(@"C:\Temp.txt"));
Eoin Campbell
quelle
4
Wird das Objekt nicht besser entsorgt? Beispiel: using (System.IO.File.Create (Dateipfad)) {}
kentaromiura
@ Kentaromiura: Meine Gedanken genau, daher meine Antwort :)
Jon Skeet
4

Sie können Methoden aus dem zurückgegebenen Objekt verketten, sodass Sie die gerade geöffnete Datei sofort in einer einzelnen Anweisung schließen können.

File.Open("filename", FileMode.Create).Close();
umilmi81
quelle
4

Um ein versehentliches Überschreiben einer vorhandenen Datei zu vermeiden, verwenden Sie:

using (new FileStream(filename, FileMode.CreateNew)) {}

... und behandeln Sie die IOException, die auftritt, wenn die Datei bereits vorhanden ist.

File.Create, was in anderen Antworten vorgeschlagen wird, überschreibt den Inhalt von, wenn die Datei bereits vorhanden ist. In einfachen Fällen können Sie dies mit abmildern File.Exists(). In Szenarien, in denen mehrere Threads und / oder Prozesse gleichzeitig versuchen, Dateien im selben Ordner zu erstellen, ist jedoch etwas Robusteres erforderlich.

Phil Haselden
quelle
2

Ein etwas häufiger Anwendungsfall für das Erstellen einer leeren Datei besteht darin, etwas anderes in einem anderen Prozess auszulösen, wenn keine komplexere Prozesskommunikation vorhanden ist. In diesem Fall kann es hilfreich sein, die Dateierstellung aus Sicht der Außenwelt atomar zu gestalten (insbesondere, wenn das ausgelöste Objekt die Datei löscht, um den Trigger zu "verbrauchen").

Daher kann es hilfreich sein, einen Junk-Namen (Guid.NewGuid.ToString ()) im selben Verzeichnis wie die zu erstellende Datei zu erstellen und dann eine Datei zu erstellen. Verschieben Sie vom temporären Namen zum gewünschten Namen. Andernfalls kann ausgelöster Code, der das Vorhandensein einer Datei überprüft und dann den Auslöser löscht, unter Rennbedingungen ausgeführt werden, bei denen die Datei gelöscht wird, bevor sie vollständig geschlossen wird.

Wenn Sie die temporäre Datei im selben Verzeichnis (und Dateisystem) haben, erhalten Sie die gewünschte Atomizität. Das gibt so etwas wie.

public void CreateEmptyFile(string path)
{
    string tempFilePath = Path.Combine(Path.GetDirectoryName(path),
        Guid.NewGuid.ToString());
    using (File.Create(tempFilePath)) {}
    File.Move(tempFilePath, path);
}
aggieNick02
quelle
0

Path.GetTempFileName () erstellt eine eindeutig benannte leere Datei und gibt den Pfad dorthin zurück.

Wenn Sie den Pfad steuern möchten, aber einen zufälligen Dateinamen erhalten möchten, können Sie GetRandomFileName verwenden, um einfach eine Dateinamenzeichenfolge zurückzugeben und diese mit Create zu verwenden

Beispielsweise:

string fileName=Path.GetRandomFileName();
File.Create("custom\\path\\" + fileName);
Crippledsmurf
quelle
IMHO GetTempFileName () ist komplett falsch benannt.
Kay.herzam
Warum genau ist diese Antwort nicht hilfreich?
Crippledsmurf
5
Es ist aus zwei Gründen nicht hilfreich: 1. Bei der Frage geht es nicht darum, einen zufälligen Dateinamen zu generieren. Das ist also eine Ablenkung. 2. Die Datei wird nicht geschlossen. Wenn Sie später versuchen, einen anderen Dateischreiber zu öffnen oder die Datei zu verschieben, schlägt dies fehl.
Fluss Satya
Ich nehme Ihre Punkte aber: 1. Alle Dateien benötigen einen Namen. Das war einfach. Bequemer Weg, um eine zu erhalten, die wahrscheinlich nicht mit irgendetwas kollidiert. 2. Die Frage zum Erstellen von Dateien, die der betreffende Code zumindest für die Verwaltung der Datei danach ausführt, ist nicht unbedingt Teil der Erstellung, daher habe ich sie für die Datei weggelassen der Einfachheit halber und um die Antwort auf die Frage zu konzentrieren
Crippledsmurf