Crear un archivo vacío en C #

186

¿Cuál es la forma más simple / canónica de crear un archivo vacío en C # /. NET?

La forma más simple que pude encontrar hasta ahora es:

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

Respuestas:

384

Usar solo File.Createdejará el archivo abierto, lo que probablemente no sea lo que desea.

Podrías usar:

using (File.Create(filename)) ;

Eso parece un poco extraño, eso sí. Podrías usar llaves en su lugar:

using (File.Create(filename)) {}

O simplemente llame Disposedirectamente:

File.Create(filename).Dispose();

De cualquier manera, si va a usar esto en más de un lugar, probablemente debería considerar envolverlo en un método auxiliar, p. Ej.

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

Tenga en cuenta que llamar Disposedirectamente en lugar de usar una usingdeclaración realmente no hace mucha diferencia aquí hasta donde puedo decir: la única forma en que podría hacer una diferencia es si el hilo se cancelara entre la llamada File.Createy la llamada a Dispose. Si existe esa condición de carrera, sospecho que también existiría en la usingversión, si el hilo se abortara al final del File.Createmétodo, justo antes de que se devolviera el valor ...

Jon Skeet
fuente
8
Gracioso. Acabo de escribir el mismo código hace unos 5 minutos. Hice File.Create (nombre de archivo) .Close (); Misma diferencia ...
Brian Genisio
2
Mi código estaba usando using (File.Create(filename)) ;, pero me encanta la simplicidad deFile.Create(filename).Dispose();
Vadim
@BrianGenisio: ¡Acabo de hacer el mismo código hace unos 5 minutos también! Simplemente busqué en Google para ver cómo lo hicieron otros programadores. Ahora estoy usando en File.Create(filename).Dispose();lugar de.
Jack
1
@ user3791372: Close()también liberará los recursos. Close()solo llamadas Dispose- vea github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/…
Jon Skeet
2
Es posible que no sea obvio que si el archivo ya existe y no es de solo lectura, el contenido del archivo se sobrescribe. Para evitar esto, useusing (new FileStream(filename, FileMode.CreateNew)) { }
Phil Haselden el
34
File.WriteAllText("path", String.Empty);

o

File.CreateText("path").Close();
conocidos
fuente
2
Usando el primero, el archivo tiene 3 bytes de longitud: el código de codificación. Usando el segundo, el archivo es de 0 bytes (realmente vacío).
Fil
1
@Fil: ¿Estás seguro? La documentación dice que File.WriteAllText(string, string)usa "codificación UTF-8 sin una marca de orden de bytes (BOM)" . Si aún ve uno, sería un error en WriteAllText o en su documentación que vale la pena informar.
Heinzi
Recuerdo que lo intenté. Tal vez fue un viejo error de la versión anterior .Net? El archivo no está vacío si especifico explícitamente usar la codificación UTF8 (o unicode u otra cosa): <File.WriteAllText ("c: \ del.txt", String.Empty, System.Text.Encoding.UTF8);>
Fil
1
@Fil, Encoding.UTF8devuelve un codificador que genera la marca de orden de bytes (BOM). Puede usar new UTF8Encoding(false)para obtener un codificador UTF8 que no genera la lista de materiales.
Daniel Crabtree
1
No sé si WriteAllTextrealmente se comporta diferente en la versión anterior de .NET. Sin embargo, para estar más seguro, simplemente omita la parte de codificación y úsela File.WriteAllBytes(path, new byte[] { });en su lugar.
Jürgen Steinblock
20
System.IO.File.Create(@"C:\Temp.txt");

Como otros han señalado, debe deshacerse de este objeto o envolverlo en una declaración de uso vacía.

using (System.IO.File.Create(@"C:\Temp.txt"));
Eoin Campbell
fuente
44
no será mejor disponer el objeto? por ejemplo: usando (System.IO.File.Create (filepath)) {}
kentaromiura
@kentaromiura: Mis pensamientos exactamente, de ahí mi respuesta :)
Jon Skeet
5

Para evitar sobrescribir accidentalmente un archivo existente, use:

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

... y maneje la IOException que ocurrirá si el archivo ya existe.

File.Create, que se sugiere en otras respuestas, sobrescribirá el contenido del archivo si ya existe. En casos simples, puede mitigar esto usando File.Exists(). Sin embargo, es necesario algo más robusto en escenarios en los que múltiples hilos y / o procesos intentan crear archivos en la misma carpeta simultáneamente.

Phil Haselden
fuente
4

Puede encadenar métodos del objeto devuelto, por lo que puede cerrar inmediatamente el archivo que acaba de abrir en una sola declaración.

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

Un caso de uso algo común para crear un archivo vacío es desencadenar que algo más suceda en un proceso diferente en ausencia de una comunicación de proceso más sofisticada. En este caso, puede ayudar que la creación del archivo sea atómica desde el punto de vista del mundo exterior (particularmente si lo que se dispara va a eliminar el archivo para "consumir" el disparador).

Por lo tanto, puede ayudar crear un nombre basura (Guid.NewGuid.ToString ()) en el mismo directorio que el archivo que desea crear, y luego hacer un File.Move desde el nombre temporal hasta el nombre deseado. De lo contrario, el código activado que verifica la existencia del archivo y luego elimina el disparador puede encontrarse en condiciones de carrera donde el archivo se elimina antes de que se cierre por completo.

Tener el archivo temporal en el mismo directorio (y sistema de archivos) le brinda la atomicidad que desee. Esto da algo así.

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

Path.GetTempFileName () creará un archivo vacío con un nombre único y le devolverá la ruta.

Si desea controlar la ruta pero obtiene un nombre de archivo aleatorio, puede usar GetRandomFileName para devolver una cadena de nombre de archivo y usarla con Crear

Por ejemplo:

string fileName=Path.GetRandomFileName();
File.Create("custom\\path\\" + fileName);
Pájaro lisiado
fuente
En mi humilde opinión GetTempFileName () está completamente mal nombrado.
kay.herzam
¿Por qué exactamente esta respuesta no es útil?
Crippledsmurf
55
No es útil por dos razones: 1. La pregunta no pregunta nada sobre la generación de un nombre de archivo aleatorio, por lo que es una distracción. 2. El archivo no se cierra, lo que significa que si luego intenta abrir otro escritor de archivos o mover el archivo, fallará.
Río Satya
Tomo sus puntos pero: 1. Todos los archivos necesitan un nombre. Eso fue un simple. forma conveniente de obtener uno que probablemente no colisionaría con nada 2. La pregunta sobre la creación de archivos, que el código en cuestión hace, como mínimo, la administración del archivo a partir de entonces no es estrictamente parte de la creación, por lo que lo omití para el en aras de la simplicidad y mantener la respuesta centrada en la pregunta
Crippledsmurf