Crie um arquivo .txt se não existir e, se anexar uma nova linha

161

Gostaria de criar um arquivo .txt e escrever nele, e se o arquivo já existir, quero acrescentar mais algumas linhas:

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

Mas a primeira linha parece sempre ser substituída ... como posso evitar escrever na mesma linha (estou usando isso em um loop)?

Eu sei que é uma coisa bem simples, mas nunca usei o WriteLinemétodo antes. Eu sou totalmente novo em c #.

Berker Yüceer
fonte
3
Cuidado que quase todas as respostas aqui estão erradas e sujeitas às condições da corrida . Lembre-se: o padrão if (file exists) { open file }quase sempre está errado em todas as linguagens de programação! Para .NET, a solução é usar File.Open(path, FileMode.Append, FileAccess.ReadWrite)com sinalizadores apropriados.
ComFreek 21/08/19
"Um valor FileMode que especifica se um arquivo é criado, se não existir, e determina se o conteúdo dos arquivos existentes é mantido ou substituído." então a mesma coisa feita pelo .net em vez da abordagem manual aqui. Portanto, não está errado aqui, é o mesmo processo feito manualmente. Você pode dizer que é ineficiente, mas dizer errado não conta.
Berker Yüceer
A diferença é: File.Opendelegar internamente a uma função WinAPI (consulte o próximo comentário), esperançosamente, impedindo a condição de corrida. A maioria das soluções aqui não faz isso e está obviamente sujeita às condições da corrida.
ComFreek 21/08/19
1
A verificação de existência, no entanto, é determinada por FileMode.Append aqui .. e direciona para uma verificação de existência e cria um arquivo com CreateFileA. Ainda dizendo errado um pouco extremo, mas você pode dizer que é ineficiente. Também não devemos esquecer que a verificação de existência não pode ser usada apenas para acesso de gravação / leitura, mas também para outros assuntos; portanto, para novos iniciantes, este tópico é útil para entender como funciona. No entanto, se você puder adicionar uma resposta, incluindo todas as definições que você escreveu aqui e a razão pela qual é melhor, isso ajudaria muito como resposta e provavelmente será escolhido como correto.
Berker Yüceer
1
@ComFreek Concordo plenamente que você deve escrever uma resposta completa sobre o assunto para explicá-lo claramente. Os comentários não servem para responder, e estou sinceramente curioso sobre essas condições de corrida e como você propõe resolvê-lo.
Matthieu Foltzer

Respostas:

167

Use o construtor correto :

else if (File.Exists(path))
{
    using(var tw = new StreamWriter(path, true))
    {
        tw.WriteLine("The next line!");
    }
}
Daniel Hilgarth
fonte
11
Primeira resposta, resposta mais simples, resposta mais útil para mim lol. Quando eu olhei, fiquei tipo: Hein? basta adicionar ", true" é suficiente? Como é que eu não vejo isso antes? Porra ... Eu me senti um total obrigado estúpido. Precio mesmo essas boas respostas.
Berker Yüceer 28/03/12
7
dica: se o arquivo não existir, este construtor criará um novo arquivo.
Abou-Emish 6/03/16
1
envolva i em um uso (veja a resposta abaixo).
David Thielen
1
Fechar é redundante, se você tem usando
Michael Freidgeim
2
-1 Isso está sujeito às condições da corrida e pode produzir um comportamento errado! Talvez use File.Open(path, FileMode.Append, FileAccess.ReadWrite)e verifique o tamanho do arquivo através desse fluxo retornado.
ComFreek 21/08/19
57
string path = @"E:\AppServ\Example.txt";
File.AppendAllLines(path, new [] { "The very first line!" });

Consulte também File.AppendAllText (). O AppendAllLines adicionará uma nova linha a cada linha sem precisar colocá-la lá.

Ambos os métodos criarão o arquivo se ele não existir, para que você não precise.

drch
fonte
3
Eu acho que isso é mais apropriado para o que o usuário estava perguntando. Parece que existem 2 problemas. 1 é que o texto é substituído - isso ocorre porque o WriteLine está substituindo o arquivo. Nesse caso, File.AppendAllText é mais apropriado. e 2) - a questão de como posso criar meu arquivo e saber que estou anexando a ele. É bom conhecê-lo. File.AppendAllText cria o arquivo, essa foi a minha pergunta. O StreamWriter nem sempre é apropriado, depende do uso desse aplicativo. De qualquer forma, isso me ajudou. +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
fonte
Também tenho o mesmo problema, e encontro esse pôster, mas as soluções aqui não resolvem o meu problema. Então, eu uso algumas soluções e apenas adiciono Dispose (). Meu objetivo não envolve copiar e colar.
Aek
1
Não estou sugerindo que sim; Estou dizendo que, sem incluir isso em sua resposta, o pôster original não saberá por que você fez as alterações que fez ou o que elas devem realizar. Sempre inclua todas as informações relevantes ao publicar, para que as pessoas saibam tudo o que você está fazendo. :)
DiMono
1
Isso funciona porque não dá um erro que diz que você não pode gravar no arquivo recém-criado porque está sendo usado por outro processo. O .Dispose () é a chave. Muito obrigado!
GenXisT
Isso não aborda de forma alguma a questão, que consiste em preservar o conteúdo existente.
Ben Voigt
Não faz sentido chamar Close()uma usingdeclaração, pois todos os recursos serão fechados antes de serem descartados automaticamente.
21416 Sheridan
21

Na verdade, você não precisa verificar se o arquivo existe, pois o StreamWriter fará isso por você. Se você o abrir no modo de acréscimo, o arquivo será criado se ele não existir, sempre será acrescentado e nunca será substituído. Portanto, seu cheque inicial é redundante.

TextWriter tw = new StreamWriter(path, true);
tw.WriteLine("The next line!");
tw.Close(); 
John Boling
fonte
1
Eu estava tentando descobrir a lógica da resposta aceita, sabia que tinha feito isso em uma linha antes, mas não conseguia lembrar a sintaxe exata. Obrigado.
Morvael 10/10/19
14

File.AppendAllText adiciona uma seqüência de caracteres a um arquivo. Ele também cria um arquivo de texto se o arquivo não existir. Se você não precisa ler o conteúdo, é muito eficiente. O caso de uso está em log.

File.AppendAllText("C:\\log.txt", "hello world\n");
R.Cha
fonte
Isso é exatamente o que eu precisava, mas como posso fazer o novo conteúdo começar em uma nova linha? Estou usando arquivos CSV.
NiallUK 22/04
Eu acho que não há uma solução simples. Eu sugiro que você verifique esta postagem. stackoverflow.com/questions/1343044/…
R.Cha
6

Você só quer abrir o arquivo no modo "anexar".

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

Ed Manet
fonte
sim, isso também é útil, mas eu estava procurando uma solução rápida e simples e, graças a @Daniel Hilgarth, ele forneceu essa solução. então +1.
Berker Yüceer 28/03/12
3

Quando você inicia o StreamWriter, ele substitui o texto que estava lá antes. Você pode usar a propriedade append da seguinte maneira:

TextWriter t = new StreamWriter(path, true);
Matan Shahar
fonte
3
 else if (File.Exists(path)) 
{ 
  using (StreamWriter w = File.AppendText(path))
        {
            w.WriteLine("The next line!"); 
            w.Close();
        }
 } 
Smack
fonte
1
Se você tiver o bloco `using ', w.Close é redundante. Descarte no final do uso do bloco, faça o mesmo.
Michael Freidgeim
-1 Isso está sujeito às condições da corrida e pode produzir um comportamento errado! Talvez use File.Open(path, FileMode.Append, FileAccess.ReadWrite)e verifique o tamanho do arquivo através desse fluxo retornado.
ComFreek 21/08/19
2

Tente isso.

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
fonte
Redudant File.AppendText(path), e com ele não há necessidade de verificar File.Exists(path). E If (not A) Else If (A)é um estranho If / Else. Basicamente, não há nada de bom nessa questão, nenhum código de explicação que seja uma versão redudante de outra resposta.
XdtTransform
-1 Isso está sujeito às condições da corrida e pode produzir um comportamento errado! Talvez use File.Open(path, FileMode.Append, FileAccess.ReadWrite)e verifique o tamanho do arquivo através desse fluxo retornado.
ComFreek 21/08/19
2

Você pode apenas usar o método File.AppendAllText (), isso resolverá o seu problema. Este método cuidará da criação do arquivo, se não estiver disponível, abrindo e fechando o arquivo.

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

Na documentação da Microsoft, você pode criar um arquivo, se não existir, e anexá-lo em uma única chamada, método File.AppendAllText (String, String)

.NET Framework (versão atual) Outras versões

Abre um arquivo, anexa a sequência especificada ao arquivo e, em seguida, fecha o arquivo. Se o arquivo não existir, esse método cria um arquivo, grava a sequência especificada no arquivo e fecha o arquivo. Espaço para nome: System.IO Assembly: mscorlib (em mscorlib.dll)

Sintaxe C # C ++ F # VB public static void AppendAllText (caminho da string, conteúdo da string) Caminho dos parâmetros Tipo: System.String O arquivo ao qual anexar a string especificada. conteúdo Tipo: System.String A cadeia de caracteres a ser anexada ao arquivo.

AppendAllText

David Fawzy
fonte
1
using(var tw = new StreamWriter(path, File.Exists(path)))
{
    tw.WriteLine(message);
}
Andreas Gusakov
fonte
Geralmente, as respostas são muito mais úteis se incluem uma explicação sobre o que o código pretende fazer e por que isso resolve o problema sem a introdução de outros.
Tim Diekmann