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 #.

Berker Yüceer
la source
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!");
    }
}
Daniel Hilgarth
la source
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.

drch
la source
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!");
   }
}
Aek
la source
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(); 
John Boling
la source
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");
R.Cha
la source
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
6

Vous voulez simplement ouvrir le fichier en mode «ajout».

http://msdn.microsoft.com/en-us/library/3zc0w663.aspx

Ed Manet
la source
oui c'est utile aussi mais je cherchais une solution rapide et simple et grâce à @Daniel Hilgarth, il a fourni cette solution. donc +1.
Berker Yüceer
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);
Matan Shahar
la source
3
 else if (File.Exists(path)) 
{ 
  using (StreamWriter w = File.AppendText(path))
        {
            w.WriteLine("The next line!"); 
            w.Close();
        }
 } 
Claque
la source
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!");
    }
}
Asiri Jayaweera
la source
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);
Vijay Shaaruck
la source
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

David Fawzy
la source
1
using(var tw = new StreamWriter(path, File.Exists(path)))
{
    tw.WriteLine(message);
}
Andreas Gusakov
la source
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