Crea un file .txt se non esiste e se aggiunge una nuova riga


161

Vorrei creare un file .txt e scriverlo, e se il file esiste già voglio solo aggiungere qualche altra riga:

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

Ma la prima riga sembra essere sempre sovrascritta ... come posso evitare di scrivere sulla stessa riga (sto usando questo in un ciclo)?

So che è una cosa abbastanza semplice, ma non ho mai usato il WriteLinemetodo prima. Sono totalmente nuovo in C #.


3
Attenzione che quasi tutte le risposte qui sono sbagliate e soggette alle condizioni di gara . Ricorda: lo schema if (file exists) { open file }è quasi sempre sbagliato in tutti i linguaggi di programmazione! Per .NET la soluzione deve essere utilizzata File.Open(path, FileMode.Append, FileAccess.ReadWrite)con flag appropriati.
ComFreek,

"Un valore FileMode che specifica se un file viene creato se non esiste e determina se i contenuti dei file esistenti vengono conservati o sovrascritti." così la stessa cosa fatta da .net invece dell'approccio manuale qui. Quindi non è sbagliato qui, è lo stesso processo fatto manualmente. Potresti dire inefficiente, ma dire male non conta.
Berker Yüceer,

La differenza è: File.Opendelegare internamente a una funzione WinAPI (vedi il prossimo commento) sperando di prevenire le condizioni di gara. La maggior parte delle soluzioni qui non lo fanno e sono ovviamente soggette alle condizioni di gara.
ComFreek,

1
Il controllo di esistenza tuttavia è determinato da FileMode.Append qui .. e indirizza a un controllo di esistenza quindi crea il file con CreateFileA. Dico ancora un po 'estremo, ma puoi dire inefficiente. Inoltre, non dobbiamo dimenticare che il controllo dell'esistenza non può essere utilizzato solo per l'accesso in lettura / scrittura, ma può essere utilizzato anche da altre questioni, quindi per i principianti questo argomento è utile per capire come funziona. Tuttavia, se puoi aggiungere una risposta includendo tutte le definizioni che hai scritto qui e il motivo per cui è meglio che sarebbe di grande aiuto come risposta e probabilmente verrà scelto come corretto.
Berker Yüceer,

1
@ComFreek Sono pienamente d'accordo che dovresti scrivere una risposta completa a riguardo per spiegarlo chiaramente. I commenti non sono per rispondere, e sono sinceramente curioso di queste condizioni di gara e di come proponi di risolverlo.
Matthieu Foltzer,

Risposte:


167

Usa il costruttore corretto :

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

11
Prima risposta, Risposta più semplice, Risposta più utile per me lol. Quando l'ho guardato ero come: eh? basta aggiungere ", vero" è sufficiente? Come mai non lo vedo prima? Dannazione ... Mi sentivo un totale stupido grazie. Precetto davvero queste buone risposte.
Berker Yüceer,

7
suggerimento: se il file non esiste, questo costruttore crea un nuovo file.
Abou-Emish

1
avvolgi i in un utilizzo (vedi risposta sotto).
David Thielen,

1
Chiudi è ridondante, se si utilizza
Michael Freidgeim il

2
-1 Questo è soggetto alle condizioni di gara e può produrre comportamenti errati! Forse preferisci usare File.Open(path, FileMode.Append, FileAccess.ReadWrite)e controllare la dimensione del file tramite quel flusso restituito.
ComFreek,

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

Vedi anche File.AppendAllText (). AppendAllLines aggiungerà una nuova riga per ogni riga senza doverlo inserire da soli.

Entrambi i metodi creeranno il file se non esiste, quindi non è necessario.


3
Penso che questo sia più appropriato per ciò che l'utente stava chiedendo. Sembra che ci siano 2 problemi. 1 è il testo sovrascritto - questo perché WriteLine sta sovrascrivendo il file. In questo caso, File.AppendAllText è più appropriato. e 2) - la domanda su come posso creare il mio file e sapere che lo sto aggiungendo. È bello saperlo File.AppendAllText crea il file, questa era la mia domanda. StreamWriter non è sempre appropriato, dipende da quale applicazione viene utilizzata. In entrambi i casi, questo mi ha aiutato. +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!");
   }
}

Anch'io ho lo stesso problema e trovo questo poster ma le soluzioni qui non risolvono il mio problema. Quindi uso alcuni pezzi di soluzione e aggiungo semplicemente Dispose (). Il mio obiettivo non prevede il copia-incolla.
Aek

1
Non sto suggerendo di averlo fatto; Sto dicendo che senza includerlo nella tua risposta, il poster originale non saprà perché hai apportato le modifiche apportate o cosa dovrebbero realizzare. Includi sempre tutte le informazioni rilevanti quando pubblichi, in modo che le persone sappiano tutto quello che stai facendo. :)
DiMono,

1
Questo funziona perché non fornisce un errore che indica che non è possibile scrivere nel file appena creato perché viene utilizzato da un altro processo. .Dispose () è la chiave. Grazie mille!
GenXisT,

Questo non risponde in alcun modo alla domanda, che riguarda la conservazione dei contenuti esistenti.
Ben Voigt,

Non ha senso chiamare Close()da usingun'istruzione, poiché tutte le risorse verranno chiuse prima di essere eliminate automaticamente.
Sheridan,

21

In realtà non devi controllare se il file esiste, poiché StreamWriter lo farà per te. Se lo si apre in modalità append, il file verrà creato se non esiste, quindi si accederà sempre e non si scriverà mai più. Quindi il tuo controllo iniziale è ridondante.

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

1
Stavo cercando di elaborare la logica della risposta accettata, sapevo di averlo già fatto in una riga ma non riuscivo a ricordare l'esatta sintassi. Grazie.
Morvael,

14

File.AppendAllText aggiunge una stringa a un file. Crea anche un file di testo se il file non esiste. Se non hai bisogno di leggere i contenuti, è molto efficiente. Il caso d'uso è la registrazione.

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

Questo è proprio quello di cui avevo bisogno, ma come posso iniziare il nuovo contenuto su una nuova linea? Sto usando i file CSV.
NiallUK,

Immagino non ci sia una soluzione semplice. Ti suggerirei di dare un'occhiata a questo annuncio. stackoverflow.com/questions/1343044/...
R.Cha


3

Quando avvii StreamWriter ha la precedenza sul testo prima. È possibile utilizzare la proprietà append in questo modo:

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
Se hai il blocco `using ', w.Chiudi è ridondante. Smaltire alla fine dell'utilizzo del blocco fa lo stesso.
Michael Freidgeim,

-1 Questo è soggetto alle condizioni di gara e può produrre comportamenti errati! Forse preferisci usare File.Open(path, FileMode.Append, FileAccess.ReadWrite)e controllare la dimensione del file tramite quel flusso restituito.
ComFreek,


2

Prova questo.

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), e con esso non c'è bisogno di controllare File.Exists(path). Ed If (not A) Else If (A)è uno strano If / Else. Fondamentalmente non c'è nulla di buono in questa domanda, nessun codice di spiegazione che è una versione ridondante di altre risposte.
xdtTransform

-1 Questo è soggetto alle condizioni di gara e può produrre comportamenti errati! Forse preferisci usare File.Open(path, FileMode.Append, FileAccess.ReadWrite)e controllare la dimensione del file tramite quel flusso restituito.
ComFreek,

2

Puoi semplicemente usare il metodo File.AppendAllText () per risolvere il tuo problema. Questo metodo si occuperà della creazione del file se non disponibile, aprendo e chiudendo il file.

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

1

Dalla documentazione di Microsoft, è possibile creare un file se non esiste e accodarlo in un'unica chiamata Metodo File.AppendAllText (String, String)

.NET Framework (versione corrente) Altre versioni

Apre un file, aggiunge la stringa specificata al file e quindi chiude il file. Se il file non esiste, questo metodo crea un file, scrive la stringa specificata nel file, quindi chiude il file. Spazio dei nomi: System.IO Assembly: mscorlib (in mscorlib.dll)

Sintassi C # C ++ F # VB vuoto statico pubblico AppendAllText (percorso stringa, contenuto stringa) Parametri percorso Tipo: System.String Il file a cui aggiungere la stringa specificata. indice Tipo: System.String La stringa da aggiungere al file.

AppendAllText


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

In generale, le risposte sono molto più utili se includono una spiegazione di ciò che il codice è destinato a fare e perché risolve il problema senza introdurre altri.
Tim Diekmann,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.