[RESOLVIDO]Cadastro de clientes, como não sobreescrever arquivos com io.FileOutputStream;?

13 respostas
D

Este método sobrescreve o cadastro dos clientes, como faço para não sobreescrever?

private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {                                           
      DataOutputStream arquivo = null;
try{
   
arquivo = new DataOutputStream(new FileOutputStream("clientes.dat"));

int aux;



String nn=JOptionPane.showInputDialog(null,"Entre com o nome do cliente para cadastrar");

String end=JOptionPane.showInputDialog(null,"Entre com o Endereco do cliente para cadastrar");

aux=Integer.parseInt(JOptionPane.showInputDialog(null,"entre con o telefone do cliente"));


arquivo.writeChars(nn);
arquivo.writeChars(end);
arquivo.writeInt(codigoDoCliente);
arquivo.writeInt(aux);
arquivo.writeChars("\n");


codigoDoCliente++; // Para nenhum cliente ter o mesmo código, o valor dele é o do ultimo cliente cadastrado mais 1
}

Um sistema que só cadastra um cliente e quando cadastra outro, sobreescreve o 1º não é nem um pouco útil...

13 Respostas

davidbuzatto

A sua dúvida é a do título?
Não dá p/ colocar ela no corpo da mensagem?
E a documentação das classes que você está utilizando, vc pelo menos deu uma olhada?

D

davidbuzatto:
A sua dúvida é a do título?
Não dá p/ colocar ela no corpo da mensagem?
E a documentação das classes que você está utilizando, vc pelo menos deu uma olhada?

Responderei na ordem, sim, é a do título, já adicionei no corpo e não intendi como assim “documentação das classes”

drsmachado
arquivo = new DataOutputStream(new FileOutputStream("clientes.dat", false));
D

drsmachado:
arquivo = new DataOutputStream(new FileOutputStream("clientes.dat", false));

Continua sobreescrevendo.

O sistema é inútil só tendo um cliente no cadastro…

emanuelCruz

O correto é FileOutputStream(“clientes.dat”,true) e não FileOutputStream(“clientes.dat”,false), pois o booleano em questão no construtor contrala exatamente se quer realizar append (acrescentar ao final) ou não.

Não esqueça de dar o flush (salvar) e close (para fechar o arquivo.

Segue exemplo:

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class Teste {

	public static void main(String[] args) {
		
		try {
			DataOutputStream arquivo = new DataOutputStream(new FileOutputStream("clientes.dat",true));
			
			arquivo.writeChars("cliente 1");  
			arquivo.writeChars("\n");  
			
			arquivo.flush();
			arquivo.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
	}
	
	
}
D
emanuelCruz:
O correto é FileOutputStream("clientes.dat",true) e não FileOutputStream("clientes.dat",false), pois o booleano em questão no construtor contrala exatamente se quer realizar append (acrescentar ao final) ou não.

Não esqueça de dar o flush (salvar) e close (para fechar o arquivo.

Segue exemplo:

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class Teste {

	public static void main(String[] args) {
		
		try {
			DataOutputStream arquivo = new DataOutputStream(new FileOutputStream("clientes.dat",true));
			
			arquivo.writeChars("cliente 1");  
			arquivo.writeChars("\n");  
			
			arquivo.flush();
			arquivo.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
	}
	
	
}

Não resolveu, ele sempre remove o cliente anterior.

Que coisa, eu não quero que ele remova o arquivo anterior, sem isto meu sistema é [n]INÚTIL[/n].

Da para perceber pelo tamanho do arquivo que ele remove todos.

davidbuzatto

DarthVictor:
davidbuzatto:
A sua dúvida é a do título?
Não dá p/ colocar ela no corpo da mensagem?
E a documentação das classes que você está utilizando, vc pelo menos deu uma olhada?

Responderei na ordem, sim, é a do título, já adicionei no corpo e não intendi como assim “documentação das classes”


O JDK possui uma documentação - http://download.oracle.com/javase/6/docs/
A da classe FileOutputStream pode ser encontrada aqui: http://download.oracle.com/javase/6/docs/api/java/io/FileOutputStream.html

Como o Emanuel falou, passe um true no segundo parâmetro do construtor de FileOutputStream para indicar que é para fazer append no arquivo caso ele já exista, não gerar um novo.

[]´s

D

davidbuzatto:
DarthVictor:
davidbuzatto:
A sua dúvida é a do título?
Não dá p/ colocar ela no corpo da mensagem?
E a documentação das classes que você está utilizando, vc pelo menos deu uma olhada?

Responderei na ordem, sim, é a do título, já adicionei no corpo e não intendi como assim “documentação das classes”


O JDK possui uma documentação - http://download.oracle.com/javase/6/docs/
A da classe FileOutputStream pode ser encontrada aqui: http://download.oracle.com/javase/6/docs/api/java/io/FileOutputStream.html

Como o Emanuel falou, passe um true no segundo parâmetro do construtor de FileOutputStream para indicar que é para fazer append no arquivo caso ele já exista, não gerar um novo.

[]´s

Sinceramente, não entendi nada desta “documentação”, só quero que ele não remova o anterior, coloquei como “true” e usei o flush e close mas continua simplesmente salvando em cima do anterior. Olhe o ultimo código que fiz:

int aux;
        try {
             DataOutputStream arquivo = new DataOutputStream(new FileOutputStream("vendedores.dat",true));

             arquivo = new DataOutputStream(new FileOutputStream("vendedores.dat"));

             String nn=JOptionPane.showInputDialog(null,"Entre com o nome do vendedor para cadastrar");

             String end=JOptionPane.showInputDialog(null,"Entre com o Endereco do vendedor para cadastrar");

             aux=Integer.parseInt(JOptionPane.showInputDialog(null,"entre con o telefone do vendedor"));

              arquivo.writeChars(";");
              arquivo.writeChars(nn);
              arquivo.writeChars(";");
              arquivo.writeChars(end);
              arquivo.writeChars(";");
              arquivo.writeInt(aux);
              arquivo.writeChars(";");
              arquivo.writeChars("\n");
              arquivo.flush();
              arquivo.close();

               } catch (FileNotFoundException e) {

    JOptionPane.showMessageDialog(null, "arquivo não encontrado");
               }
          catch (IOException e) {
              JOptionPane.showMessageDialog(null, "Erro ao cadastrar vendedor");
         }

==============================================================================================

Agora eu vi que passei true no parâmetro errado, agora deu certo :

arquivo = new DataOutputStream(new FileOutputStream("clientes.dat",true));
davidbuzatto

É, desenvolver alguma coisa sem saber o que está fazendo e ir se baseando em tentativa e erro realmente pode ser muito frustrante.
Faça um pouco de esforço e tente entender a documentação. Não é ciência de foguetes, isso posso te garantir.

Veja as linhas 02 e 04 do seu código… Me responda: o que você está fazendo nessas duas linhas?

[]´s

D

davidbuzatto:
É, desenvolver alguma coisa sem saber o que está fazendo e ir se baseando em tentativa e erro realmente pode ser muito frustrante.
Faça um pouco de esforço e tente entender a documentação. Não é ciência de foguetes, isso posso te garantir.

[]´s

É, talvez seja melhor estudar a documentação nos casos futuros, só tenho problemas pois não sei o que significa algumas palavras, mas nada que um dicionário resolva…

E não estou tentando no tentativa e erro, se estivesse, mal teria feito metade do sistema que pediram…

davidbuzatto

Veja as linhas 02 e 04 do seu código.

drsmachado

Sei que o tópico está marcado como resolvido, mas, há cerca de um mês eu desenvolvi um trabalho para um amigo, cujo objetivo era utilizar o FileInputStream e o FileOutputStream.
Desta forma, utilizei o seguinte código, pois o mesmo atendia os requisitos propostos pelo problema, que era para gravar objetos de classes que posteriormente seriam recuperados e utilizados em cálculos estatísticos.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class gravaObj {

    FileOutputStream fos;
    ObjectOutputStream oos;
    Object obj;
    List ll;

    public void serializa(Object obj, String arq) {
        try {
            File ff = new File(arq);
            if (ff.exists()) {
                leObj lo = new leObj();
                ll = (ArrayList) lo.le(arq);
                ll.add(obj);
            } else {
                ll = new ArrayList();
                ll.add(obj);
            }
            fos = new FileOutputStream(ff, false);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(ll);
            oos.flush();
            oos.close();
            fos.close();
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        }
    }
}

Na época até cheguei a colocar no GUJ uma pergunta sobre como ler mais de um objeto gravado, pois o FileInputStream não possui um método como o nextLine() da classe Scanner.
O mesmo permite perfeitamente a inclusão de vários objetos e, esta classe faz a leitura destas sem qualquer perda (desconsiderando performance, é claro)

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;

public class leObj {

    List lista = new ArrayList();
    FileInputStream fis;
    ObjectInputStream ois;

    public List le(String arq) {
        try {
            fis = new FileInputStream(arq);
            ois = new ObjectInputStream(fis);
            lista = (ArrayList) ois.readObject();
        } catch (ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }finally{
            return lista;
        }
    }
}

Como podem observar, os códigos não ficaram tão elegantes como poderiam, mas se efetuarem um teste simples, verão que são extremamente funcionais.
Classe dos objetos a serem serializados

import java.io.Serializable;

public class Obj implements Serializable {
    int cod;
    String nome;

    public int getCod() {
        return cod;
    }

    public void setCod(int cod) {
        this.cod = cod;
    }

    public String getNome() {
        return nome;
    }

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

Classe de teste

import java.util.List;
import javax.swing.JOptionPane;
import util.gravaObj;
import util.leObj;

public class Teste {
    public static void main(String[] args) {
        int x=0;
        Obj obs = new Obj();
        do{
            obs.setCod(Integer.parseInt(JOptionPane.showInputDialog("Código ")));
            obs.setNome(JOptionPane.showInputDialog("Nome "));
            gravaObj go = new gravaObj();
            go.serializa(obs, "C:\\arq1.com");
            x = Integer.parseInt(JOptionPane.showInputDialog("Deseja continuar (1) Sim (0) Não"));
        }while(x != 0);
        leObj lo = new leObj();
        List l = lo.le("C:\\arq1.com");
        for(int y = 0; y < l.size(); y++){
            Obj t = (Obj)l.get(y);
            System.out.println(y+" "+t.getCod()+" "+t.getNome());
        }
    }
}

É uma alternativa.

D

drsmachado:
Sei que o tópico está marcado como resolvido, mas, há cerca de um mês eu desenvolvi um trabalho para um amigo, cujo objetivo era utilizar o FileInputStream e o FileOutputStream.
Desta forma, utilizei o seguinte código, pois o mesmo atendia os requisitos propostos pelo problema, que era para gravar objetos de classes que posteriormente seriam recuperados e utilizados em cálculos estatísticos.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class gravaObj {

    FileOutputStream fos;
    ObjectOutputStream oos;
    Object obj;
    List ll;

    public void serializa(Object obj, String arq) {
        try {
            File ff = new File(arq);
            if (ff.exists()) {
                leObj lo = new leObj();
                ll = (ArrayList) lo.le(arq);
                ll.add(obj);
            } else {
                ll = new ArrayList();
                ll.add(obj);
            }
            fos = new FileOutputStream(ff, false);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(ll);
            oos.flush();
            oos.close();
            fos.close();
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        }
    }
}

Na época até cheguei a colocar no GUJ uma pergunta sobre como ler mais de um objeto gravado, pois o FileInputStream não possui um método como o nextLine() da classe Scanner.
O mesmo permite perfeitamente a inclusão de vários objetos e, esta classe faz a leitura destas sem qualquer perda (desconsiderando performance, é claro)

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;

public class leObj {

    List lista = new ArrayList();
    FileInputStream fis;
    ObjectInputStream ois;

    public List le(String arq) {
        try {
            fis = new FileInputStream(arq);
            ois = new ObjectInputStream(fis);
            lista = (ArrayList) ois.readObject();
        } catch (ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }finally{
            return lista;
        }
    }
}

Como podem observar, os códigos não ficaram tão elegantes como poderiam, mas se efetuarem um teste simples, verão que são extremamente funcionais.
Classe dos objetos a serem serializados

import java.io.Serializable;

public class Obj implements Serializable {
    int cod;
    String nome;

    public int getCod() {
        return cod;
    }

    public void setCod(int cod) {
        this.cod = cod;
    }

    public String getNome() {
        return nome;
    }

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

Classe de teste

import java.util.List;
import javax.swing.JOptionPane;
import util.gravaObj;
import util.leObj;

public class Teste {
    public static void main(String[] args) {
        int x=0;
        Obj obs = new Obj();
        do{
            obs.setCod(Integer.parseInt(JOptionPane.showInputDialog("Código ")));
            obs.setNome(JOptionPane.showInputDialog("Nome "));
            gravaObj go = new gravaObj();
            go.serializa(obs, "C:\\arq1.com");
            x = Integer.parseInt(JOptionPane.showInputDialog("Deseja continuar (1) Sim (0) Não"));
        }while(x != 0);
        leObj lo = new leObj();
        List l = lo.le("C:\\arq1.com");
        for(int y = 0; y < l.size(); y++){
            Obj t = (Obj)l.get(y);
            System.out.println(y+" "+t.getCod()+" "+t.getNome());
        }
    }
}

É uma alternativa.

Nossa, me ajudou e muito, daqui a alguns dias eu ia programar cálculos “doidos” como estes e muito obrigado, ajudou e muito para coisas futuras que irei ter de fazer…

Criado 13 de novembro de 2010
Ultima resposta 13 de nov. de 2010
Respostas 13
Participantes 4