Tworzenie pustego pliku w C #


186

Jaki jest najprostszy / kanoniczny sposób utworzenia pustego pliku w C # / .NET?

Najprostszym sposobem, jaki udało mi się znaleźć do tej pory, jest:

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

Odpowiedzi:


384

Użycie just File.Createpozostawi plik otwarty, co prawdopodobnie nie jest tym, czego chcesz.

Możesz użyć:

using (File.Create(filename)) ;

To trochę dziwne, pamiętaj. Zamiast tego możesz użyć nawiasów klamrowych:

using (File.Create(filename)) {}

Lub po prostu zadzwoń Disposebezpośrednio:

File.Create(filename).Dispose();

Tak czy inaczej, jeśli zamierzasz użyć tego w więcej niż jednym miejscu, prawdopodobnie powinieneś rozważyć zapakowanie go w metodę pomocniczą, np.

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

Należy pamiętać, że dzwoniąc Disposebezpośrednio zamiast używać usingoświadczenie naprawdę nie robi dużej różnicy tutaj o ile mogę powiedzieć - tylko w ten sposób, że mógł dokonać różnica jest jeśli wątek zostały przerwane między wywołaniu File.Createi wywołaniu Dispose. Jeśli ten warunek wyścigu istnieje, podejrzewam, że istniałby również w usingwersji, gdyby wątek został przerwany na samym końcu File.Createmetody, tuż przed zwróceniem wartości ...


8
Zabawny. Właśnie napisałem ten sam kod około 5 minut temu. Zrobiłem File.Create (nazwa pliku) .Close (); Ten sam
— trudny

2
Mój kod był używany using (File.Create(filename)) ;, ale uwielbiam prostotęFile.Create(filename).Dispose();
— Vadim

@BrianGenisio: Zrobiłem ten sam kod około 5 minut temu! Właśnie googlowałem, żeby zobaczyć, jak zrobili to inni programiści. Teraz używam File.Create(filename).Dispose();zamiast.
— Jack

1
@ user3791372: Close()zwolni również zasoby. Close()tylko połączenia Dispose- patrz github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/…
— Jon Skeet

1
Może nie być oczywiste, że jeśli plik już istnieje i nie jest tylko do odczytu, zawartość pliku zostanie zastąpiona. Aby tego uniknąć, użyjusing (new FileStream(filename, FileMode.CreateNew)) { }
— Phil Haselden

34
File.WriteAllText("path", String.Empty);

lub

File.CreateText("path").Close();

2
Używając pierwszego, plik ma 3 bajty: kodowanie. Używając sekundy plik ma 0 bajtów (naprawdę jest pusty).
— Fil

1
@Fil: Jesteś pewien? Dokumentacja mówi, że File.WriteAllText(string, string)używa „kodowania UTF-8 bez znaku Byte-Order Mark (BOM)” . Jeśli nadal go widzisz, byłby to błąd w WriteAllText lub jego dokumentacji, którą warto zgłosić.
— Heinzi

Pamiętam, że próbowałem. Może to był stary błąd poprzedniej wersji .Net? Plik nie jest pusty, jeśli wyraźnie podam kodowanie UTF8 (lub Unicode lub coś innego): <File.WriteAllText („c: \ del.txt”, String.Empty, System.Text.Encoding.UTF8);>
— Fil

1
@Fil, Encoding.UTF8zwraca koder, który wyprowadza znak Byte Order Mark (BOM). Możesz użyć, new UTF8Encoding(false)aby uzyskać koder UTF8, który nie generuje BOM.
— Daniel Crabtree

1
Nie wiem, czy WriteAllTextnaprawdę zachowuje się inaczej w poprzedniej wersji .NET. Jednak dla większej pewności po prostu pomiń część kodującą i użyj File.WriteAllBytes(path, new byte[] { });zamiast tego.
— Jürgen Steinblock

20
System.IO.File.Create(@"C:\Temp.txt");

Jak zauważyli inni, powinieneś pozbyć się tego obiektu lub zawinąć go w pustą instrukcję using.

using (System.IO.File.Create(@"C:\Temp.txt"));

4
nie lepiej pozbyć się obiektu? np .: using (System.IO.File.Create (
— ścieżka pliku

@kentaromiura: Dokładnie moje myśli, stąd moja odpowiedź :)
— Jon Skeet

4

Możesz powiązać metody ze zwróconym obiektem, dzięki czemu możesz natychmiast zamknąć plik, który właśnie otworzyłeś w jednej instrukcji.

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

4

Aby uniknąć przypadkowego zastąpienia istniejącego pliku, użyj:

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

... i obsłuż wyjątek IOException, który pojawi się, jeśli plik już istnieje.

File.Create, co jest sugerowane w innych odpowiedziach, zastąpi zawartość, jeśli plik już istnieje. W prostych przypadkach można to złagodzić za pomocą File.Exists(). Jednak coś bardziej niezawodnego jest konieczne w scenariuszach, w których wiele wątków i / lub procesów próbuje jednocześnie utworzyć pliki w tym samym folderze.


2

Nieco powszechnym przypadkiem użycia do utworzenia pustego pliku jest wywołanie czegoś innego w innym procesie przy braku bardziej wyrafinowanej komunikacji procesu. W takim przypadku pomocne może być tworzenie pliku bez użycia atomu z punktu widzenia świata zewnętrznego (szczególnie jeśli rzecz, która zostanie uruchomiona, usunie plik, aby „wykorzystać” wyzwalacz).

Może więc pomóc stworzyć niepotrzebną nazwę (Guid.NewGuid.ToString ()) w tym samym katalogu, co plik, który chcesz utworzyć, a następnie wykonać File.Move z nazwy tymczasowej na pożądaną nazwę. W przeciwnym razie kod uruchamiany, który sprawdza istnienie pliku, a następnie usuwa wyzwalacz, może uruchomić się w warunkach wyścigu, w których plik jest usuwany przed całkowitym zamknięciem.

Posiadanie pliku tymczasowego w tym samym katalogu (i systemie plików) zapewnia atomowość, jakiej możesz potrzebować. To daje coś takiego.

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

0

Path.GetTempFileName () utworzy pusty plik o unikalnej nazwie i zwróci do niego ścieżkę.

Jeśli chcesz kontrolować ścieżkę, ale chcesz uzyskać losową nazwę pliku, możesz użyć GetRandomFileName, aby po prostu zwrócić ciąg nazwy pliku i użyć go z opcją Utwórz

Na przykład:

string fileName=Path.GetRandomFileName();
File.Create("custom\\path\\" + fileName);

IMHO GetTempFileName () jest całkowicie błędnie nazwany.
— kay.herzam

Dlaczego dokładnie ta odpowiedź nie jest pomocna?
— Crippledsmurf

5
Jest to nieprzydatne z dwóch powodów: 1. Pytanie nie dotyczy pytania o wygenerowanie losowej nazwy pliku, więc to rozprasza. 2. Plik nie zostanie zamknięty, co oznacza, że ​​jeśli później spróbujesz otworzyć inny program zapisujący pliki lub przenieść plik, zakończy się niepowodzeniem.
— Rzeka Satya,

Rozumiem twoje uwagi, ale: 1. Wszystkie pliki wymagają nazwy. To było proste. wygodny sposób, aby uzyskać taki, który prawdopodobnie nie koliduje z niczym 2. Pytanie zadawane o tworzenie plików, które w danym pytaniu minimalnie zarządza plikiem, nie jest już ściśle częścią tworzenia, więc pominąłem to dla ze względu na prostotę i skoncentrowanie odpowiedzi na pytaniu
— Crippledsmurf,
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.