Gravar e ler arquivos .txt

Meu professor de POO passou um trabalho que consiste em criar uma lista encadeada sem usar array. Já consegui fazer todos os tópicos, mas ainda falta gravar a lista e lê-la de um arquivo .txt.
A lista é composta por objetos da classe pessoa, que contém os seguintes métodos:

   private String nome;
   private long CPF;
   private long Matricula;
   private long tel;
   private String end;
   private String email;
   private int id;
   int IdCad;
   protected static int Contador1, Contador0;
   public Pessoa next = null;  // referencia o proximo objeto da lista

Como fazer isso? Obrigado desde já.

Olá,

Acredito que por se tratar de um trabalho de estudo, é proibido utilizar qualquer tipo de biblioteca que faça isso para você automaticamente, certo? Minha resposta é baseada nisso.

Você vai precisar criar meio que um protocolo para (de)serializar essa estrutura em uma (Input/Output)Stream. Eu bolei uma ideia aqui, talvez você ou outro usuário consigam pensar em algo melhor. É apenas uma sugestão, sempre há várias maneiras de resolver os problemas. Eu discordo da abordagem de que a classe Pessoa deve ter a lógica da lista encadeada, mas de novo, esse é um trabalho acadêmico e acredito que boas práticas de eng. de software e design de classes ainda não estão em foco aqui.

Faz o seguinte:

  1. Cria um método em Pessoa mais ou menos assim: escreverEm(PrintWritter alvo), onde alvo pode representar uma stream de arquivo ou de qualquer outra coisa (como a rede, por exemplo). A lógica desse método vai ser mais ou menos assim:

    1. O objeto pessoa da vez (no qual o método foi chamado) vai se escrever na stream alvo (já trato essa parte).

    2. Se seu next não estiver null, o objeto vai chamar o método escreverEm no seu next, de forma recursiva.

       public void escreverEm(PrintWritter alvo) {
           // escreve os próprios atributos em alvo
           if (next != null) // se existe next, que ele se escreva no alvo
               next.escreverEm(alvo);
       }
      
  2. A ideia é que, no código cliente (no main, provavelmente), você vai fazer assim:

     public static void main(String... args) {
         Pessoa primeiroNo = // toda a lógica para criar uma estrutura de lista encadeada de pessoas
         PrintWritter alvo = new PrintWritter("nomeDoArquivoDeSaida");
         primeiroNo.escreverEm(alvo);
         alvo.close();
     }
    

    Para não me estender demais, não vou abordar o tratamento de Exceptions nem o funcionamento de streams, acredito que você já saiba se virar sozinho. Se não souber, faz uma pergunta nova que a gente te responde lá depois!

  3. Voltando para a parte no passo 1 onde falei sobre a lógica de escrever os atributos na stream:

    1. Você vai precisar inventar um protocolo para delimitar os dados. Você pode fazer algo assim no arquivo de texto: separa os atributos de uma mesma pessoa por quebra de linha, na ordem em que eles aparecem na classe. Exemplo:

       lucas
       738.361.186-33
       //matricula
       //tel
       //end
       //email
       //id
       //IdCad
      

      Você pode também nomear os valores (nome: lucas) dentro do arquivo. Enfim, não faz a menor diferença. Como é você que escreve, você vai saber como ler e interpretar o arquivo.

  4. A parte da leitura do arquivo é exatamente igual. Você vai criar um método novo, o lerDe(BufferedReader fonte), que vai fazer o trabalho contrário do método escreverEm. Também, de forma recursiva, algo assim:

     public static Pessoa lerDe(BufferedReader fonte) {
         // 1. lê os atributos de pessoa na ordem que foram escritos da stream fonte
         // 2. cria um objeto Pessoa com esses atributos
         // 3. verifica se a stream fonte ainda tem dados
         // 3.1 se tem, chama o lerDe(fonte) recursivamente e seta o resultado no next da pessoa criada no passo 2
         // Retorna a pessoa criada no passo 2
     }
1 curtida

Cara, acredito que não tenha problema em usar bibliotecas que façam isso automaticamente… Mas eu procurei em vários lugares, e ainda assim não consegui encontrar uma solução concreta… O que eu imaginei, foi um .txt guardando todos os atributos de cada pessoa inserida na lista, separando uma instância por linha. Porém, a classe pessoa é autorreferenciável, então tem um atributo dela que é outra classe pessoa. Não sei como isso entraria no .txt. Mas o trabalho é pra hoje até meia noite, então creio que vou enviar sem ler/escrever no txt, mesmo. De qualquer forma, muito obrigado pela ajuda!

até a próxima :wink:

Para Escrever, ou adicione um throws ou coloque um try catch, pode ser com IOException ou somente Exception, utilize o método Files.write
Ele vai pedir um Path, você pode utilizar um File ou então o Paths.get que fica no mesmo pacote que a classe Files
E vai pedir também um byte, no caso, se você quer escrever uma String, java.lang.String tem um metodo chamado getBytes que retorna os “byte[]” do arquivo
Para ler, utilize o metodo Files.readAllBytes que vai retornar um byte[]
Para transforma-lo de volta em String, e so usar:
String nome = new String(Files.readAllBytes…);
ele pede um Path, pode ser de um File ou da classe Paths