Persistência de Dados - Manipulando Vetor e Arquivos de Texto
Hello Devs
Ferreira outra vez com vocês, no primeiro artigo do ano, desejando um Feliz Ano Novo a todos, muita paz, saúde e sucesso para nós.
A verdade é que eu gostaria de ter trazido esta publicação a muito tempo, mas infelizmente quando surgiu a ideia eu não tinha propriedade suficiente para falar sobre, mas após alguns perrengues tentando implementar as opções nos meus: Projeto ByteBank e Jogo da Velha adquiri level suficiente para tankar esse assunto, ou pelo menos o básico dele.
Tudo que descreverei nessa publicação pode ser considerado uma POC (Prova de Conceito), e como o próprio nome sugere nada mais é do que testar a viabilidade de algo, seja um projeto, um produto ou uma ideia, e verificar dentre vários quesitos a viabilidade, portanto cabe a você decidir qual método utilizar.
Dados sem persistência
Na verdade esse termo acabei de inventar aqui, se ele existe em algum lugar desconheço mas já utilizei dessa técnica para simulador dados cadastrados, a ideia aqui é simplesmente registrarmos os dados em uma variável seja ela do tipo que melhor atender suas necessidades, importante ressaltar que isso não é persistência de dados, pois ao encerrar o programa tudo será perdido.
Exemplo:
A ideia aqui é preenchermos uma HashSet com 15 nomes de clientes, e foi decidido pela regra de negócio implícita que esses nomes não serão repetidos, podem sim existir mais de um primeiro nome igual, ou mais de um sobrenome igual, mas nunca haverá nome e sobrenome iguais.
Dessa forma conseguimos acessar nossa lista de nomes de clientes, entretanto todas as vezes que o programa for executado será formada uma nova carteira de clientes, que podem ou não ser igual a última vez em que a aplicação foi iniciada.
Arquivo de texto
De agora em diante as opções começam a se expandir, pois o C# possui diversas classes para a manipulação de arquivos, vejamos:
File : Essa classe fornece métodos estáticos para criar, ler, abrir, fechar e excluir arquivos, além de obter informações sobre arquivos, como o tamanho e a data de criação.
FileStream : Permite a leitura e gravação de arquivos binários.
StreamReader: Permite ler um fluxo de caracteres a partir de um arquivo de texto. Ela tem métodos para ler caracteres ou linhas individuais ou ler o arquivo inteiro de uma só vez.
StreamWriter: Escreve um fluxo de caracteres em um arquivo de texto. Essa classe tem métodos para escrever caracteres ou linhas individuais ou escrever no final do arquivo.
StringReader: Le um fluxo de caracteres a partir de uma string. Ela tem métodos semelhantes à StreamReader para ler caracteres ou linhas individuais ou ler a string inteira de uma só vez.
StringWriter: Também escreve um fluxo de caracteres em uma string. Ela tem métodos semelhantes à StreamWriter para escrever caracteres ou linhas individuais ou escrever no final da string.
Basicamente essas são as principais classes, agora o mais importante é sabemos como faremos a manipulação do registro dentro desse arquivo para utilizarmos de forma prática, perceba que cada classe para manipulação possui uma função específica, ou seja, uma classe é somente para leitura enquanto outra é para gravação.
Para o nosso exemplo utilizaremos uma abordagem na qual cada linha representa um cliente:
Além disso utilizaremos o caractere : para realizar a separação das informações, isso porque ao utilizaremos o método ReadAllLines, no qual deve ser atribuído ao vetor de string, cada linha do arquivo de texto representará uma posição no vetor.
Para lermos os registros:
Isso ainda poderia ser feito utilizando POO criando uma classe, que poderíamos nomeá-la como cliente.
Para excluirmos um registro:
Da mesma forma podemos utilizar diversos métodos para excluir um registro, optai o método "Where" do LINQ (Language Integrated Query) que é usado para filtrar os elementos de um array de acordo com uma determinada condição, que é especificada através de uma expressão lambda. No caso, a expressão lambda cpf => !cpf.Contains(CPFaExcluir), significa: Para cada elemento "cpf" do vetor, mantenha-o se ele for diferente de CPFaExcluir.
Para gravarmos um registro:
Existem varias formas de adicionar um novo registro, no caso fizemos um AppendAllText que irá abrir o arquivo em modo de adição (ou seja, não sobrescreve o arquivo, mas adiciona novas informações ao final dele) e escrever a string especificada no final do arquivo.
Observe que estamos adicionando uma quebra de linha (Environment.NewLine) ao final da string para garantir que o novo registro seja adicionado em uma nova linha.
Para atualizarmos um registro:
Esse talvez deva ser o método mais complicado, pois não podemos alterar nenhum registro além do que desejamos. Iniciamos lendo todo o arquivo em um array Clientes, fazemos uma iteração percorrendo cada index do vetor que corresponde as linhas do arquivo, fora utilizado o : para realizar a separação do arquivo e realizar a alteração na linha que desejamos de acordo com a validação do if, por fim remontamos o registro na mesma linha com o método string.Join. E por fim reescrevemos por cima do arquivo existente todas as linhas do registro que foi percorrida.
Conciderações Finais
Pessoal, isso é apenas uma demonstração de conceito, vocês podem e devem modificar esses métodos para alcançar seus próprios objetivos, não realizamos nenhum tipo de tratamento, nenhuma validação, é apenas para mostrar como é possível realizar um CRUD com arquivo de texto.
E para próximo artigo será como realizar isso com uma arquivo JSON e talvez em um Banco de Dados real, vai depender do feedback de vocês nesse artigo.
E para mantermos a tradição:

Linked from:
Jackson @Jacksontop muito bom depois vou dar uma lida mais aprofundada e aproveitar algumas coisa
Parabens!!!!
Lucas Ferreira @lksferreiraExcelente, acredito que a manipulação de arquivos é essencial para outras práticas, é importante que existe e futuramente aprofundarmos.
Em resposta alksferreira⬆:Larissa Leal @LariLealNunca tinha visto o hashset, ele é como se fosse um vetor? Porém indicado para manipular arquivos txt?
Lucas Ferreira @lksferreiraHashSet é uma List, que nunca pode ter valores iguais.
- Em resposta aLariLeal⬆:
Lucas Ferreira @lksferreiraExemplo:
List
List<string> nomes = new(); nomesList.Add("Larissa"); nomesList.Add("Larissa"); nomesList.Add("Larissa"); Foreach (var nome in nomesList) { Console.WriteLine(nome); }Saída:
Larissa
Larissa
LarissaHashSet
HashSet<string> nomes = new(); nomesList.Add("Larissa"); nomesList.Add("Lucas"); nomesList.Add("Larissa"); nomesList.Add("Lucas"); nomesList.Add("Larissa"); nomesList.Add("Luca"); Foreach (var nome in nomesList) { Console.WriteLine(nome); }Saída:
Larissa
Lucas
Luca
Larissa Leal @LariLealAcho que entendi, eu até consigo "adicionar", o vs não reclama de escrever vários add. com conteúdos iguais, mas ele considera apenas 1. No final o HashSet nomes = new(); vai ser composto por apenas um elemento. É isso?
Lucas Ferreira @lksferreiraPor elementos não repetidos.
- Em resposta aLariLeal⬆:
Lucas Ferreira @lksferreiraDa uma olhada de novo no exeplo, modifiquei ele
Larissa Leal @LariLealAcho que agora compreendi melhor, obrigda!
Lucas Ferreira @lksferreiraPoe a mão na massa, tenta usar esses exemplos codando, modifica os valores, faz os testei, ai não tem como errar.
Larissa Leal @LariLealEu fiz uns teste e super funcionou, valeu!
Em resposta alksferreira⬆:Gabriel de Araújo Santos @gabrielSantosMuito bacana Lucas, muito boa e completa a explicação!
Lucas Ferreira @lksferreiraObrigado, estamos sempre por aqui.
Em resposta alksferreira⬆:André Filipe @andresantosSe você ainda não implementou a gravação de dados em arquivo de texto, recomendo criar um pequeno projeto no VS só para isso.
Escolha alguma das classes citadas e tente fazer o CRUD com apenas duas linhas no arquivo. Depois que conseguir, será mais fácil usar o JSON, por exemplo.
Observe que após alguns minutos ou horas testando a persistência de dados no projeto separado, você precisará apenas copiar o código e colar no ByteBank.
Como alguém já disse: faz o básico primeiro, depois as adições.
Lucas Ferreira @lksferreiraExatamente, o importante é entender o conceito, tornando possível a replicação em uma escala maior.
Em resposta alksferreira⬆:Matheus Henrique @MatheusHenrique95Isso aqui é uma mão na roda, explicação com exemplo prático é sempre mais fácil de entender! Vlw por dedicar tempo, Lucas.
Lucas Ferreira @lksferreiraMas você só vai realmente fixar o aprendizado se você replicar isso aqui na sua máquina, então mãos a obra.
Em resposta alksferreira⬆:André Filipe @andresantosParabéns, monitor Lucas. Mais uma publicação necessária!
Lucas Ferreira @lksferreiraHahahaha, as ideia
- BEm resposta alksferreira⬆:Breno Galvão @breno.galvao
Parabéns!
Muito bom, ajuda bastante!
Lucas Ferreira @lksferreiraFico feliz, volte sempre ^^
Em resposta alksferreira⬆:Natasha Lima @natashalimaÓtimo saber sobre isso, vou estudar melhor o assunto mas sua explicação ajudou muito, pode trazer um arquivo explicando com exemplos as diversas classes para a manipulação de arquivos?
Lucas Ferreira @lksferreiraObrigado, mas só não entendi sua pergunta, mas eu acho que coloquei as classes nessa publicação.
Natasha Lima @natashalimaEu vi as classes, perguntei se poderia exemplificar cada uma pois vi que conceito mas com exemplos práticos de cada uma será melhor para entender.
Em resposta alksferreira⬆:Bruno Coelho @BrunoCoelhoExcelente Lucas!
Muito boa a publicação. Rica em informações e exemplos.
Gostei de conhecer o HashSet.
Lucas Ferreira @lksferreiraObrigado pelo feedback