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 |
|---|---|
|
Grava uma string sem pular linha |
|
Grava uma string e já pula pra próxima linha |
|
Força a gravação do buffer no arquivo (quase nunca precisa usar na mão) |
/ |
Fecha o stream e libera o recurso (o using faz isso) |
|
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]
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.
GO TO FULL VERSION