CodeGym /Cursos /C# SELF /Gravando arquivos de texto:

Gravando arquivos de texto: StreamWriter

C# SELF
Nível 36 , Lição 3
Disponível

1. Introdução

StreamWriter é uma das classes chave do namespace System.IO no .NET, feita pra facilitar a gravação de dados de texto em arquivos via stream.

Por que não usar logo o FileStream?
FileStream só trabalha com bytes. Se você tentar gravar uma string com ele, vai ter que converter o texto pra bytes na mão e se preocupar com a codificação (aí você vai querer voltar pro StreamWriter rapidinho).
O StreamWriter cuida de tudo isso pra você: você passa uma string — ele grava os bytes certos no arquivo.

Principais vantagens:

  • Fácil escrever strings sem pensar em conversão pra bytes.
  • Tem métodos pra gravar texto linha por linha.
  • Dá pra controlar bufferização e codificação (e a gente ainda vai aprender a usar isso).

Exemplo mais simples

using System.IO;

string path = "output.txt";

using (StreamWriter writer = new StreamWriter(path))
{
    writer.WriteLine("Oi, mundo!");
    writer.WriteLine("Essa é a segunda linha.");
}
// Depois do bloco using, o StreamWriter libera o arquivo certinho.

O que tá rolando aqui?

  • O arquivo é aberto pra gravação (se não existir, ele é criado).
  • Cada string é gravada como uma linha separada no arquivo (método WriteLine).
  • Depois do bloco using, o arquivo fecha automaticamente, mesmo se der erro.

Se você abrir o arquivo output.txt depois de rodar esse programa, vai ver duas linhas de texto, do jeitinho que era pra ser.

Detalhe importante

Se o arquivo já existir, ele vai ser sobrescrito do zero! Tudo que tava lá dentro — some. Então cuidado: não guarda sua monografia ou o único comprovante do boleto nesse arquivo, beleza?

2. Gravando dados no stream

Métodos principais do StreamWriter

Método Descrição
Write(string)
Grava uma string sem pular linha
WriteLine(string)
Grava uma string e já pula pra próxima linha
Flush()
Força a gravação do buffer no arquivo (quase nunca precisa usar na mão)
Close()
/
Dispose()
Fecha o stream e libera o recurso (o using faz isso)
BaseStream
Pega acesso ao stream base (tipo FileStream)

Método Write()

Grava dados sem pular pra próxima linha. Tudo que você escrever depois vai ficar na mesma linha do arquivo.

Método WriteLine()

Grava dados e já adiciona o caractere de fim de linha (\r\n no Windows, \n em sistemas tipo Unix).
É como apertar Enter depois de cada gravação.

Write() vs WriteLine(): mostrando a diferença

using (var writer = new StreamWriter("example.txt"))
{
    writer.Write("Primeiro ");
    writer.Write("parágrafo. ");
    writer.WriteLine("Terminou a linha, Enter!");
    writer.Write("Segundo parágrafo.");
}

Agora o example.txt vai ficar mais ou menos assim:

Primeiro parágrafo. Terminou a linha, Enter!
Segundo parágrafo.

3. Trabalhando com codificações

Por padrão, quando você cria um StreamWriter sem passar parâmetros, ele usa a codificação UTF-8 com BOM (Byte Order Mark).

Na prática isso é moderno e prático, mas às vezes você precisa definir a codificação — tipo pra compatibilidade com programas antigos ou dados importados.

Como definir a codificação?

// Grava o arquivo em Windows-1251 (cirílico pra sistemas antigos)
using (var writer = new StreamWriter("cyrillic.txt", false, System.Text.Encoding.GetEncoding("windows-1251")))
{
    writer.WriteLine("Oi, mundo cirílico!");
}

Detalhe importante:
A codificação tem que ser suportada no sistema. Se não tiver certeza — vai de UTF-8.

4. Parâmetros extras do construtor

Bora dar uma olhada nos bastidores do StreamWriter:

public StreamWriter(
    string path,              // caminho do arquivo
    bool append = false,      // adicionar no final do arquivo?
    Encoding encoding = null, // codificação
    int bufferSize = 1024     // tamanho do buffer, em bytes
)
  • append — se false (padrão), o arquivo vai ser sobrescrito. Se true, novas linhas vão pro final.
  • encoding — codificação usada.
  • bufferSize — tamanho do buffer interno pra acelerar gravação de grandes volumes de dados.

Exemplo: adicionando no mesmo arquivo

// O arquivo vai ser só complementado, não sobrescrito
using (var writer = new StreamWriter("log.txt", append: true))
{
    writer.WriteLine(DateTime.Now + " -- Novo evento");
}

5. Dicas úteis

O que rola ao adicionar ou sobrescrever

Modo O que faz? Resultado no arquivo
append: false Sobrescreve tudo do zero Os dados antigos somem
append: true Adiciona novas linhas no final As linhas antigas ficam lá

Dica: O modo de adicionar (append: true) é perfeito pra logs, quando você quer guardar o histórico dos eventos.

StreamWriter e grandes volumes de dados

  • StreamWriter faz bufferização: os dados reais vão pro arquivo um pouco depois que você chama WriteLine. Mas depois de fechar o stream (ou chamar Flush()), tudo vai pro disco certinho.
  • Gravar com WriteLine é super eficiente pra saída linha a linha. Pra formatos mais complexos (JSON, CSV ou XML), melhor usar libs próprias, ou tomar cuidado pra escapar caracteres especiais (tipo vírgula ou aspas).

Como finalizar a gravação e liberar recursos do jeito certo

O jeito certo: sempre usa using!
Assim você garante que o arquivo vai fechar, mesmo se der exceção (tipo se o disco "acabar" ou outro programa travar o arquivo).


flowchart TD
    A[Criando StreamWriter] --> B[Trabalhando com o arquivo]
    B --> C{Exceção?}
    C -- Sim --> D[Dispose é chamado]
    C -- Não --> D
    D --> E[Arquivo fechado garantido]
Esquema: using garante o fechamento do arquivo mesmo com erro

6. Exemplos práticos

Imagina que no curso a gente tem um mini-programa de cadastro de livros. Vamos adicionar a função de gravar novos livros num arquivo.

Exemplo: Salvando um novo livro em arquivo separado

using System;
using System.IO;

class Program
{
    static void Main()
    {
        Console.WriteLine("Digite o nome do livro:");
        string bookTitle = Console.ReadLine();

        Console.WriteLine("Digite o autor:");
        string author = Console.ReadLine();

        string path = "books.txt";
        using (var writer = new StreamWriter(path, append: true))
        {
            writer.WriteLine($"{bookTitle};{author}");
            // Formato CSV: cada linha é um livro, separado por ponto e vírgula
        }

        Console.WriteLine("Livro salvo no arquivo!");
    }
}

Tenta adicionar vários livros seguidos. No arquivo books.txt as linhas vão sendo adicionadas, sem apagar as anteriores. Esse jeito é ótimo pra logs ou históricos — tipo pra sua futura auditoria quando você virar dev Enterprise.

7. Como evitar erros comuns ao gravar em arquivo

A maioria dos iniciantes tropeça nesses problemas:

Arquivo não fechado e travado por outro processo. Motivo — esqueceu do using.

Gravou várias linhas, mas o arquivo ficou vazio: esqueceu de chamar Flush() ou fechar o stream (com using isso rola automático).

Acabou sobrescrevendo o arquivo em vez de adicionar — esqueceu de passar append: true.

Problemas de codificação: o arquivo abre "tudo estranho" no Bloco de Notas — escolheu a codificação errada ou o outro programa não suporta UTF-8.

Exceções UnauthorizedAccessException ou DirectoryNotFoundException: o programa tentou salvar o arquivo num lugar sem permissão ou numa pasta que não existe. Confere o caminho e as permissões.

Erro "file is used by another process": você abriu o arquivo pra gravar e não fechou, ou alguém mais tá tentando gravar nele ao mesmo tempo.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION