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


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!");
    }
}

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.


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!");
   }
}

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

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");

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


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

3
 else if (File.Exists(path)) 
{ 
  using (StreamWriter w = File.AppendText(path))
        {
            w.WriteLine("The next line!"); 
            w.Close();
        }
 } 

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!");
    }
}

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

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


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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.