C# - Salvando uma lista de objetos em um arquivo texto
Hoje vamos recordar uma operação básica que todo o desenvolvedor C# deve saber: salvar uma lista para um arquivo texto. |
Eu já apresentei os fundamentos sobre como ler e escrever em arquivos textos neste artigo : C# - Lendo e escrevendo em arquivos textos (StreamReader/StreamWriter)
Hoje vamos aplicar esses conceitos em uma tarefa prática bem comum : Salvar uma lista para um texto.
Então vamos supor que você tenha uma lista de objetos representado por List<T> e deseja salvar esta lista em um arquivo no formato .txt.
Vamos criar uma aplicação console (.NET Core) List_Text1 no ambiente do .NET 5.0 .
No projeto crie uma pasta Data e nesta pasta defina a classe Contato que representa o nosso objeto para o qual vamos gerar a lista e a seguir gerar o arquivo texto.
public class Contato { public int Id { get; set; } public string Nome { get; set; } public string Email { get; set; } public string Telefone { get; set; } } |
A seguir vamos criar a pasta Services e nesta pasta criar a classe ContatoService onde vamos criar os seguintes métodos:
Todos os métodos descritos acima serão estáticos de forma a podermos usá-los sem necessitar da instância da classe.
1- GetContatos()
public static List<Contato> GetContatos() { var lista = new List<Contato> { new Contato() {Id = 1, Nome = "Maria", Email = "maria@email.com", Telefone="13-8760-9909"}, new Contato() {Id = 2, Nome = "Paulo", Email = "paulo@email.com", Telefone="12-9981-0919"}, new Contato() {Id = 3, Nome = "Beatriz", Email = "bibi@yahoo.com", Telefone="11-9956-4098"}, new Contato() {Id = 4, Nome = "Janice", Email = "jan@hotmail.com", Telefone="21-9850-0034"}, new Contato() {Id = 5, Nome = "Mario", Email = "mario@email.com", Telefone="17-6580-1122"} }; return lista; } |
Neste código estamos gerando uma lista com 5 objetos Contato e retornando a lista.
2- SalvarListaParaTexto(IEnumerable<T> lista, string arquivo, char separador)
public static bool SalvarListaParaTexto<T>(IEnumerable<T> lista, string arquivo, char separador) { try { using (var sw = File.CreateText(arquivo)) { var plist = typeof(T).GetProperties().Where(p => p.CanRead && (p.PropertyType.IsValueType || p.PropertyType == typeof(string)) && p.GetIndexParameters().Length == 0).ToList(); if (plist.Count > 0) sw.WriteLine(string.Join(seperator, plist.Select(p => p.Name))); |
Neste código estamos recebendo a lista de objetos como um IEnumerable<T> assim podemos ter como fonte tabelas, listas, dicionários, etc. Recebemos também o nome do arquivo texto que será gerado e o separador das colunas que serão geradas.
Criamos o arquivo texto usando o método File.CreateText()
em uma declaração using para liberar os
recursos usando a interface IDisposable. Em
seguida, precisamos coletar as informações das propriedades do tipo T. Pedimos
as informações das propriedades que podemos ler, o tipo de propriedade é um tipo
de valor ou string e não é um indexador.
Se a lista de informações da propriedade contiver pelo menos uma informação de
propriedade, podemos continuar. Precisamos gerar os cabeçalhos das colunas.
Usamos para isso o método string.Join para
construir o cabeçalho da coluna da lista de informações da propriedade.
Agora podemos começar a escrever as linhas de dados para cada objeto em nossa
lista. E faremos isso em 4 etapas:
1- Precisamos criar uma lista genérica de objetos para nossos dados;
2- Para cada informação de propriedade na lista de informações de propriedade,
coletamos um valor e o armazenamos na lista de dados;
3- A seguir construímos a linha usando a função string.Join
e a salvamos em um arquivo;
4- No final, fechamos um arquivo (o método Dispose
fará isso);
3- ExibirArquivoTexto(string path)
public static void ExibirArquivoTexto(string path) { if (File.Exists(path)) { using (StreamReader sr = File.OpenText(path)) { string s = ""; while ((s = sr.ReadLine()) != null) { Console.WriteLine(s); } } } else { Console.WriteLine($"Arquivo {path} não encontrado"); } } |
Neste código
passamos o caminho e nome do arquivo texto gerado, e, após verificar a sua
existência percorremos o arquivo e exibimos o seu conteúdo.
Testando a implementação
Na classe Program vamos definir o código abaixo e testar a nossa implementação
using List_Text1.Services; using System; namespace List_Text1 Console.WriteLine("Salvando uma lista de objetos em um arquivo texto\n"); try |
No código acima estamos usando como separado a tabulação '\t'.
A execução do projeto irá apresentar o seguinte resultado:
Podemos ainda implementar a opção para não salvar o header no arquivo texto incluindo o parâmetro cabecalho :
public static void ExportarParaArquivo<T>(this List<T> listaDados, string nomeArquivo, char ColunaSeparador, bool cabecalho)
e alterando a linha de código :
if(cabecalho)
sw.WriteLine(string.Join(seperador, lista.Select(p
=> p.Name)));
A chamada agora pode ser feita assim: <lista>.ExportarParaArquivo(arquivo, ',', false);
Pegue o código do projeto aqui : List_Text1.zip
"Toda a Escritura é divinamente inspirada, e proveitosa
para ensinar, para redargüir, para corrigir, para instruir em justiça;"
2 Timóteo 3:16
Referências: