Créer un fichier .txt s'il n'existe pas, et s'il ajoute une nouvelle ligne


161

Je voudrais créer un fichier .txt et y écrire, et si le fichier existe déjà, je veux juste ajouter quelques lignes supplémentaires:

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

Mais la première ligne semble toujours être écrasée ... comment éviter d'écrire sur la même ligne (j'utilise ceci en boucle)?

Je sais que c'est une chose assez simple, mais je n'ai jamais utilisé la WriteLineméthode auparavant. Je suis totalement nouveau sur C #.


3
Attention, presque toutes les réponses ici sont fausses et soumises aux conditions de course . Rappelez-vous: le modèle if (file exists) { open file }est presque toujours faux dans tous les langages de programmation! Pour .NET, la solution consiste à utiliser File.Open(path, FileMode.Append, FileAccess.ReadWrite)avec les indicateurs appropriés.
ComFreek

"Une valeur FileMode qui spécifie si un fichier est créé s'il n'en existe pas et détermine si le contenu des fichiers existants est conservé ou écrasé." donc même chose faite par .net au lieu de l'approche manuelle ici. Donc ce n'est pas faux ici, c'est le même processus fait manuellement. Vous pouvez dire inefficace mais dire faux ne compte pas.
Berker Yüceer

La différence est: File.Opendélègue en interne à une fonction WinAPI (voir le commentaire suivant), espérons-le, empêchant la condition de concurrence. La plupart des solutions ici ne font pas cela et sont assez évidemment soumises aux conditions de course.
ComFreek

1
Le contrôle d'existence est cependant déterminé par FileMode.Append ici .. et il dirige vers un contrôle d'existence puis crée un fichier avec CreateFileA. Toujours dire mal un peu extrême, mais vous pouvez dire inefficace. Nous ne devons pas non plus oublier que la vérification d'existence ne peut pas être utilisée uniquement pour l'accès en écriture / lecture peut également être utilisée pour d'autres questions.Pour les nouveaux débutants, cette rubrique est donc utile pour comprendre comment cela fonctionne. Cependant, si vous pouvez ajouter une réponse comprenant toutes les définitions que vous avez écrites ici et la raison pour laquelle c'est mieux, cela aiderait beaucoup en tant que réponse et sera probablement choisie comme correcte.
Berker Yüceer

1
@ComFreek Je suis tout à fait d'accord que vous devriez écrire une réponse complète à ce sujet pour l'expliquer clairement. Les commentaires ne sont pas faits pour répondre, et je suis sincèrement curieux de connaître ces conditions de course et de savoir comment vous proposez de les résoudre.
Matthieu Foltzer

Réponses:


167

Utilisez le bon constructeur :

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

11
Première réponse, réponse la plus simple, réponse la plus utile pour moi lol. Quand je l'ai regardé, je me suis dit: Hein? il suffit d'ajouter ", vrai"? Pourquoi je ne verrai pas ça avant Merde ... Je me sentais complètement stupide merci. J'apprécie vraiment ces bonnes réponses.
Berker Yüceer

7
astuce: si le fichier n'existe pas, ce constructeur crée un nouveau fichier.
Abou-Emish

1
envelopper i dans une utilisation (voir la réponse ci-dessous).
David Thielen

1
Fermer est redondant, si vous utilisez
Michael Freidgeim

2
-1 Ceci est soumis aux conditions de course et peut produire un mauvais comportement! Peut-être plutôt utiliser File.Open(path, FileMode.Append, FileAccess.ReadWrite)et vérifier la taille du fichier via ce flux renvoyé.
ComFreek

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

Voir aussi File.AppendAllText (). AppendAllLines ajoutera une nouvelle ligne à chaque ligne sans avoir à la mettre vous-même.

Les deux méthodes créeront le fichier s'il n'existe pas afin que vous n'ayez pas à le faire.


3
Je pense que c'est plus approprié pour ce que l'utilisateur demandait. On dirait qu'il y a 2 problèmes. 1 signifie que le texte est écrasé - c'est parce que WriteLine écrase le fichier. Dans ce cas, File.AppendAllText est plus approprié. et 2) - la question de savoir comment créer mon fichier et savoir que j'y ajoute. Il est bon de le savoir File.AppendAllText crée le fichier, c'était ma question. StreamWriter n'est pas toujours approprié, cela dépend de l'utilisation de cette application. Dans les deux cas, cela m'a aidé. +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!");
   }
}

J'ai le même problème aussi et je trouve cette affiche, mais les solutions ici ne résolvent pas mon problème. J'utilise donc quelques éléments de solution et j'ajoute simplement Dispose (). Mon objectif n'implique pas de copier-coller.
Aek

1
Je ne suggère pas que ce soit le cas; Je dis que sans l'inclure dans votre réponse, l'affiche originale ne saura pas pourquoi vous avez apporté les modifications que vous avez apportées ou ce qu'elles sont censées accomplir. Incluez toujours toutes les informations pertinentes lorsque vous publiez, afin que les gens sachent tout ce que vous faites. :)
DiMono

1
Cela fonctionne car cela ne donne pas d'erreur indiquant que vous ne pouvez pas écrire dans le fichier nouvellement créé car il est utilisé par un autre processus. Le .Dispose () est la clé. Merci beaucoup!
GenXisT

Cela ne répond en aucun cas à la question, qui consiste à préserver le contenu existant.
Ben Voigt

Il est inutile d'appeler à Close()partir d'une usinginstruction, car toutes les ressources seront fermées avant d'être supprimées automatiquement.
Sheridan

21

Vous n'êtes pas obligé de vérifier si le fichier existe, car StreamWriter le fera pour vous. Si vous l'ouvrez en mode ajout, le fichier sera créé s'il n'existe pas, alors vous l'ajouterez toujours et ne le surchargerez jamais. Votre vérification initiale est donc redondante.

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

1
J'essayais de trouver la logique de la réponse acceptée, je savais que j'avais déjà fait cela en une seule ligne mais je ne me souvenais pas de la syntaxe exacte. Je vous remercie.
Morvael

14

File.AppendAllText ajoute une chaîne à un fichier. Il crée également un fichier texte si le fichier n'existe pas. Si vous n'avez pas besoin de lire le contenu, c'est très efficace. Le cas d'utilisation est la journalisation.

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

C'est exactement ce dont j'avais besoin, mais comment puis-je faire démarrer le nouveau contenu sur une nouvelle ligne? J'utilise des fichiers CSV.
NiallUK le

Je suppose qu'il n'y a pas de solution simple. Je vous suggère de consulter cette publication. stackoverflow.com/questions/1343044/…
R.Cha


3

Lorsque vous démarrez StreamWriter, il remplace le texte avant. Vous pouvez utiliser la propriété append comme ceci:

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
Si vous avez un bloc «using», w.Close est redondant. Disposer à la fin de l'utilisation du bloc fait de même.
Michael Freidgeim

-1 Ceci est soumis aux conditions de course et peut produire un mauvais comportement! Peut-être plutôt utiliser File.Open(path, FileMode.Append, FileAccess.ReadWrite)et vérifier la taille du fichier via ce flux renvoyé.
ComFreek


2

Essaye ça.

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), et avec lui pas besoin de vérifier File.Exists(path). Et If (not A) Else If (A)c'est un étrange If / Else. Fondamentalement, il n'y a rien de bon dans cette question, pas de code d'explication qui soit une version rédudante d'une autre réponse.
xdtTransform

-1 Ceci est soumis aux conditions de course et peut produire un mauvais comportement! Peut-être plutôt utiliser File.Open(path, FileMode.Append, FileAccess.ReadWrite)et vérifier la taille du fichier via ce flux renvoyé.
ComFreek

2

Vous pouvez simplement utiliser la méthode File.AppendAllText () pour résoudre votre problème. Cette méthode se chargera de la création du fichier s'il n'est pas disponible, de l'ouverture et de la fermeture du fichier.

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

1

À partir de la documentation Microsoft, vous pouvez créer un fichier s'il n'existe pas et y ajouter en un seul appel File.AppendAllText, méthode (chaîne, chaîne)

.NET Framework (version actuelle) Autres versions

Ouvre un fichier, ajoute la chaîne spécifiée au fichier, puis ferme le fichier. Si le fichier n'existe pas, cette méthode crée un fichier, écrit la chaîne spécifiée dans le fichier, puis ferme le fichier. Espace de noms: System.IO Assembly: mscorlib (dans mscorlib.dll)

Syntaxe C # C ++ F # VB public static void AppendAllText (chemin de la chaîne, contenu de la chaîne) Paramètres chemin Type: System.String Le fichier auquel ajouter la chaîne spécifiée. contents Type: System.String La chaîne à ajouter au fichier.

AppendAllText


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

En général, les réponses sont beaucoup plus utiles si elles incluent une explication de ce que le code est censé faire et pourquoi cela résout le problème sans en présenter d'autres.
Tim Diekmann
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.