Lendo varios objetos de um arquivo texto ObjectInputStream

Boa tarde Pessoal este é meu primeiro topico, la vai minha duvida, estou começando a aprender Java em casa, estudando e lendo documentações. To fazendo um programa de uma agenda simples que grava os contatos em um arquivo txt.
Ate agora ja consegui fazer a gravação dos dados atravez do ObjectOutputStream e tambem consegui ler os dados com o ObjectInputStream, só que só consigo ler o primeiro objeto gravado no arquivo.

Abaixo segue todo meu codigo e classes.
Main

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException, FileNotFoundException, ClassNotFoundException {
        // pegando dados do usuario

        Scanner input = new Scanner(System.in); 
        Contato novo = new Contato();
        System.out.println("Digite o nome ");
        novo.setNome(input.nextLine());
        System.out.println("Digite o endereço ");
        novo.setEnd(input.nextLine());
        System.out.println("Digite o telefone ");
        novo.setTel(input.nextLine());
        System.out.println("Digite o email ");
        novo.setEmail(input.nextLine());

        novo.print();

        System.out.println("Teste com leituras e gravaçoes");
        Arquivo registro = new Arquivo();
        System.out.println("gravando dados"); //gravaçao dos dados
        registro.gravaDados(novo);
        System.out.println("lendo arquivo");
        registro.leDados();
}
    }

Classe Contato

package agendatelefonica;
import java.io.*;
/**
 *
 * @author net
 */
public class Contato implements Serializable {
private String nome;
private String endereco;
private String tel;
private String email;
private boolean test = false;
private File arquivo = new File("arquivo.txt");

//metodos
public void setNome(String nome){
    this.nome = nome;

}
public void setEnd(String end){
    this.endereco = end;
}
public void setTel(String tel){
    this.tel = tel;
}
public void setEmail(String email){
    this.email = email;
}
public String getNome(){
    return this.nome;
}
public String getEnd(){
    return this.endereco;
}
public String getTel(){
    return this.tel;
}
public String getEmail(){
    return this.email;
}
public void print(){
    System.out.println("Nome: " + this.nome);
    System.out.println("Endereco: " + this.endereco);
    System.out.println("Telefone: " + this.tel);
    System.out.println("Nome " + this.email);
}

//construtores
public Contato(){

}
public Contato(String nome){
    this.nome = nome;
}
public Contato(String nome, String end, String tel, String email){
    this.nome = nome;
    this.endereco = end;
    this.tel = tel;
    this.email = email;
}


}

Classe Arquivo É AQUI QUE ESTA MINHA DUVIDA.

package agendatelefonica;
import java.io.*;

/**
 *
 * @author net
 */
public class Arquivo implements Serializable{
    private boolean test = false;
    private File arquivo = new File("arquivo.txt");

public void gravaDados(Contato registro) throws IOException{
test = arquivo.exists();
if(test =! true){
    arquivo.createNewFile();
}
    FileOutputStream fos = new FileOutputStream("arquivo.txt",true);
    ObjectOutputStream writer = new ObjectOutputStream(fos);
    writer.writeObject(registro);
    writer.flush();
    writer.close();
    fos.flush();
    fos.close();
   
}
public void leDados() throws FileNotFoundException, IOException, ClassNotFoundException{
test = arquivo.exists();
if(test =! true){
  System.out.println("Arquivo não existe");
}else{
    FileInputStream fis = new FileInputStream("arquivo.txt");
    ObjectInputStream reader = new ObjectInputStream(fis);
    Contato registro = (Contato) reader.readObject(); // quero ler todo arquivo e colocar num array da classe Contato é possivel?
   
    registro[i].print(); // mostra o conteudo para teste
    reader.close();
    fis.close();
}
}
public Arquivo(){

}

}

Eu acho que é um arquivo pra cada objeto. To pesquisando aqui, peraí…

Se você for fazer um arquivo pra cada objeto, coloque eles em uma pasta, tipo \myApp\contatos, daí você itera pelos arquivos dessa pasta e le todos os objetos que você quiser, tipo:

char s = File.separatorChar; //Separador de caminho do sistema operacional, no windows é '\' e no linux é '/' File pasta = new File(s+"Temp"+s+"contatos"); File[] arquivos = pasta.listFiles(); FileInputStream fis = null; ObjectInputStream reader = null; Contato registro = null; List<Contato> contatos = new ArrayList<Contato>(); try { for(File arquivo : arquivos){ fis = new FileInputStream(arquivo); reader = new ObjectInputStream(fis); registro = (Contato) reader.readObject(); contatos.add(registro); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }

Vou tentar fazer assim com 1 arquivo para cada contato, mas isso nao vai complicar um pouco se eu precisar organizar ou mostrar os contatos?

Nesse caso não necessariamente, pois ali eu coloquei os contatos em um ArrayList, mas poderia ser qualquer outra estrutura de dados. A maioria das estruturas do java implementam Collection, que tem um método sort() que ordena, por exemplo rsrs…

Mas acho que para isso, sua classe Contato vai ter que implementar a interface Comparable, não sei direito. Dá uma olhada no método sort() depois…

Mas ainda assim, eu particularmente acharia melhor utilizar um banco de dados…

Tenta o seguinte:

Cria um ArrayList e insere teus objetos contatos nele.

Dai tu grava o arrayList no arquivo ao invés de gravar cada objeto.

depois quando tu for realizar a leitura, armazena o resultado do método readObject() em um Arraylist…

Depois eh só acessar as posições desse arrayList e recuperar teus objetos.

Tenta usar um while que percorra os objetos até null, deve funcionar da mesma forma como se estivesse gravado como string. Algo assim:

Contato[] registro = new Contato[10];
while (reader.readObject() != null) {
    registro[i] = reader.readObject;
}

[quote=_vinicios]Tenta o seguinte:

Cria um ArrayList e insere teus objetos contatos nele.

Dai tu grava o arrayList no arquivo ao invés de gravar cada objeto.

depois quando tu for realizar a leitura, armazena o resultado do método readObject() em um Arraylist…

Depois eh só acessar as posições desse arrayList e recuperar teus objetos.

[/quote]
Acho que não há necessidade de criar um ArrayList pra serializar os objetos pois eles são gravados em ordem no arquivo. Basta recuperar os mesmos na ordem e ir colocando num Array.

[quote]

Acho que não há necessidade de criar um ArrayList pra serializar os objetos pois eles são gravados em ordem no arquivo. Basta recuperar os mesmos na ordem e ir colocando num Array.[/quote]

Mas o que ele vai serializar é o Objeto ArrayList. e não os contatos individuais.

Se não estou enganado(nas versões anteriores do java era assim, não sei se na atual foi modificado ou não), o método readObject( ) não retorna null quando temos o final de arquivo, ele gera uma exception do tipo EOFException.

Não to em casa agora pra testar as sugestões.

Valeu pessoal! :smiley:

Gravar como Objeto ArrayList funciona, mas fiquei com dúvida de fazer como eu falei…procurei na documentação e não encontrei nda, talvez não tenha como percorrer o arquivo desta forma "/

Aproveitando o topico aqui, estou gravando os objetos assim:

[code]ArrayList lista = new ArrayList();
lista.add(usuario);

	objGravar.writeObject(lista);

[/code]

E tentando ler assim: ArrayList<Contato> lista = (ArrayList<Contato>) objLeitura.readObject();

Mas obtenho: java.lang.ClassCastException: Contato cannot be cast to java.util.ArrayList

Qual o problema??