Créer un fichier vide en C #

186

Quelle est la manière la plus simple / canonique de créer un fichier vide en C # / .NET?

Le moyen le plus simple que j'ai pu trouver jusqu'à présent est:

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

Réponses:

384

Utiliser juste File.Createlaissera le fichier ouvert, ce qui n'est probablement pas ce que vous voulez.

Vous pouvez utiliser:

using (File.Create(filename)) ;

Cela semble un peu étrange, remarquez. Vous pouvez utiliser des accolades à la place:

using (File.Create(filename)) {}

Ou appelez simplement Disposedirectement:

File.Create(filename).Dispose();

Quoi qu'il en soit, si vous comptez l'utiliser à plusieurs endroits, vous devriez probablement envisager de l'envelopper dans une méthode d'aide, par exemple

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

Notez que l' appel Disposedirectement au lieu d'utiliser une usingdéclaration ne fait pas vraiment beaucoup de différence ici autant que je peux dire - la seule façon qu'il pourrait faire une différence si le thread a été interrompu entre l'appel à File.Createet l'appel à Dispose. Si cette condition de concurrence existe, je soupçonne qu'elle existerait également dans la usingversion, si le thread était abandonné à la toute fin de la File.Createméthode, juste avant que la valeur ne soit renvoyée ...

Jon Skeet
la source
8
Drôle. Je viens d'écrire le même code il y a environ 5 minutes. J'ai fait File.Create (filename) .Close (); Même diff ...
Brian Genisio
2
Mon code utilisait using (File.Create(filename)) ;, mais j'adore la simplicité deFile.Create(filename).Dispose();
Vadim
@BrianGenisio: J'ai juste fait le même code il y a environ 5 minutes aussi! Je viens de googler pour voir comment les autres programmeurs l'ont fait. Maintenant, j'utilise File.Create(filename).Dispose();au lieu de.
Jack
1
@ user3791372: Close()libérera également les ressources. Close()appelle juste Dispose- voir github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/…
Jon Skeet
2
Il n'est peut-être pas évident que si le fichier existe déjà et n'est pas en lecture seule, le contenu du fichier est écrasé. Pour éviter cela, utilisezusing (new FileStream(filename, FileMode.CreateNew)) { }
Phil Haselden
34
File.WriteAllText("path", String.Empty);

ou

File.CreateText("path").Close();
knocte
la source
2
En utilisant le premier, le fichier fait 3 octets: le code d'encodage. En utilisant le second, le fichier est de 0 octet (vraiment vide).
Fil
1
@Fil: Êtes-vous sûr? La documentation indique qu'il File.WriteAllText(string, string)utilise "l'encodage UTF-8 sans marque d'ordre d'octet (BOM)" . Si vous en voyez toujours un, ce serait un bogue dans WriteAllText ou dans sa documentation qui mérite d'être signalé.
Heinzi
Je me souviens que j'ai essayé. C'était peut-être un vieux bogue de la version précédente de .Net? Le fichier n'est pas vide si je spécifie explicitement d'utiliser l'encodage UTF8 (ou unicode ou autre chose): <File.WriteAllText ("c: \ del.txt", String.Empty, System.Text.Encoding.UTF8);>
Fil
1
@Fil, Encoding.UTF8renvoie un encodeur qui génère la marque d'ordre d'octet (BOM). Vous pouvez utiliser new UTF8Encoding(false)pour obtenir un encodeur UTF8 qui ne génère pas la nomenclature.
Daniel Crabtree
1
Je ne sais pas si WriteAllTextse comporte vraiment différemment dans la version précédente de .NET. Cependant, pour être plus sûr, ignorez simplement la partie encodage et utilisez à la File.WriteAllBytes(path, new byte[] { });place.
Jürgen Steinblock
20
System.IO.File.Create(@"C:\Temp.txt");

Comme d'autres l'ont souligné, vous devez supprimer cet objet ou l'envelopper dans une instruction using vide.

using (System.IO.File.Create(@"C:\Temp.txt"));
Eoin Campbell
la source
4
ne sera pas mieux disposer l'objet? par exemple: en utilisant (System.IO.File.Create (filepath)) {}
kentaromiura
@kentaromiura: Mes pensées exactement, d'où ma réponse :)
Jon Skeet
5

Pour éviter d'écraser accidentellement un fichier existant, utilisez:

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

... et gérer l'exception IOException qui se produira si le fichier existe déjà.

File.Create, ce qui est suggéré dans d'autres réponses, écrasera le contenu du fichier s'il existe déjà. Dans des cas simples, vous pouvez atténuer ce problème en utilisant File.Exists(). Cependant, quelque chose de plus robuste est nécessaire dans les scénarios où plusieurs threads et / ou processus tentent de créer des fichiers dans le même dossier simultanément.

Phil Haselden
la source
4

Vous pouvez chaîner des méthodes hors de l'objet retourné, de sorte que vous pouvez immédiatement fermer le fichier que vous venez d'ouvrir dans une seule instruction.

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

Un cas d'utilisation assez courant pour créer un fichier vide est de déclencher quelque chose d'autre qui se passe dans un processus différent en l'absence de communication de processus plus sophistiquée. Dans ce cas, il peut être utile que la création de fichier soit atomique du point de vue du monde extérieur (en particulier si la chose déclenchée va supprimer le fichier pour «consommer» le déclencheur).

Il peut donc être utile de créer un nom indésirable (Guid.NewGuid.ToString ()) dans le même répertoire que le fichier que vous souhaitez créer, puis de faire un File.Move du nom temporaire au nom souhaité. Sinon, le code déclenché qui vérifie l'existence du fichier puis supprime le déclencheur peut se trouver dans des conditions de concurrence où le fichier est supprimé avant d'être complètement fermé.

Avoir le fichier temporaire dans le même répertoire (et le même système de fichiers) vous donne l'atomicité que vous voudrez peut-être. Cela donne quelque chose comme.

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

Path.GetTempFileName () créera un fichier vide au nom unique et lui renverra le chemin.

Si vous souhaitez contrôler le chemin mais obtenir un nom de fichier aléatoire, vous pouvez utiliser GetRandomFileName pour simplement renvoyer une chaîne de nom de fichier et l'utiliser avec Create

Par exemple:

string fileName=Path.GetRandomFileName();
File.Create("custom\\path\\" + fileName);
Crippledsmurf
la source
IMHO GetTempFileName () est complètement mal nommé.
kay.herzam
Pourquoi exactement cette réponse n'est-elle pas utile?
Crippledsmurf
5
Cela ne sert à rien pour deux raisons: 1. La question ne demande rien sur la génération d'un nom de fichier aléatoire, c'est donc une distraction. 2. Le fichier ne se ferme pas, ce qui signifie que si vous essayez ultérieurement d'ouvrir un autre enregistreur de fichiers ou de déplacer le fichier, il échouera.
Rivière Satya
Je prends note de vos points, mais: 1. Tous les fichiers ont besoin d'un nom. C'était simple. moyen pratique d'en obtenir un qui ne risquait pas d'entrer en collision avec quoi que ce soit 2. La question posée sur la création de fichiers, que le code en question fait, au minimum, la gestion du fichier par la suite ne fait pas strictement partie de la création, donc je l'ai omise pour le par souci de simplicité et en gardant la réponse concentrée sur la question
Crippledsmurf