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

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

[code]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
}
[/code]

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

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?

[quote=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?[/quote]

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

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

[quote=drsmachado] arquivo = new DataOutputStream(new FileOutputStream("clientes.dat", false)); [/quote]

Continua sobreescrevendo.

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

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();
		}  
	}
	
	
}

[quote=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:

[code]
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();
	}  
}

}
[/code][/quote]

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.

[quote=DarthVictor][quote=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?[/quote]

Responderei na ordem, sim, é a do título, já adicionei no corpo e não intendi como assim “documentação das classes”[/quote]
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

[quote=davidbuzatto][quote=DarthVictor][quote=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?[/quote]

Responderei na ordem, sim, é a do título, já adicionei no corpo e não intendi como assim “documentação das classes”[/quote]
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
[/quote]

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));

É, 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

[quote=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[/quote]

É, 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…

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

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.

[quote=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.
[/quote]

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…