Duvida com arquivo

30 respostas
B

opa… estou com uma duvidazinha sobre como gravar objetos em arquivo…

eu criei os seguintes metodos para gravar e ler objetos:

public void gravaObj(Processo proce){
        try {
            FileOutputStream f = new FileOutputStream ("computador.arq");
            ObjectOutputStream s = new ObjectOutputStream(f);
            s.writeObject(proce);
            s.flush();
            s.close();
            f.flush();
            f.close();
            System.out.println("Gravacao realizada com sucesso!");
        }catch (Exception e){
            System.out.println(e);
        }
    }
    public Processo leObj(){
        Processo pro = new Processo();
        try {
            FileInputStream f = new FileInputStream("computador.arq");
            ObjectInputStream s = new ObjectInputStream(f);
            pro = (Processo)s.readObject();
            s.close();
            f.close();
            
        }catch (Exception e) {
            System.out.println(e);
        }
        return pro;
    }

o problema e quando eu chamo o metodo de gravar mais de uma vez… quando ele vai gravar o novo objeto, ele apaga o que ja estava gravado(meio que grava por cima)

o que eu faco para ele gravar o novo objeto sem apagar o anterior?!

se alguem pode me ajuda…

Obrigado.

30 Respostas

DavidUser

A idéia mais comum, seria:
Fazer a leitura do arquivo, capturar seu conteudo e regravar adcionando o conteúdo anterior e fazendo a nova gravação.

Vou ver oq faço aki

DavidUser

post sua Classe Processo.

B

A idéia mais comum, seria:
Fazer a leitura do arquivo, capturar seu conteudo e regravar adcionando o conteúdo anterior e fazendo a nova gravação.

Eu ate pensei nisso… mas achei tao feio apagar td para reescrever…

Nao sei em que isso ajuda mas como vc pediu:

public class Processo<P> implements Serializable{
    private P  dataAbertura, titulo, assunto;
    private  P identificador;
    public Processo next;
    
    /*
     * Contrutor sem parâmetros - todos os atributos são vazios
     */
    public Processo(){
        setIdentificador((P) new Integer(10000));
        setDataAbertura(null);
        setTitulo(null);
        setAssunto(null); 
    }

    /*
     * Contrutor com parâmetros - atribuindo novos valores a todos os tributos
     */
    public Processo(P identificador, P dataAbertura, P titulo, P assunto){
        setIdentificador(identificador);
        setDataAbertura(dataAbertura);
        setTitulo(titulo);
        setAssunto(assunto);
    }

    /*
     * Atualiza o identificador do processo
     * @param id novo valor do atributo identificador
     */
    public void setIdentificador(P identificador) { 
        if (identificador == null) identificador = (P) new Integer(0);
        this.identificador = identificador;
    }
    /*
     * Recupera o identificador do processo
     * @return valor do atributo identificador
     */
    public P getIdentificador() { 
        return this.identificador;
    }

    /*
     * Atualiza a data de abertura do processo
     * @param data novo valor do atributo dataAbertura
     */
    public void setDataAbertura(P dataAbertura) { 
        this.dataAbertura = dataAbertura;
    }
    /*
     * Recupera o identificador do processo
     * @return valor do atributo identificador
     */
    public P getDataAbertura() { 
        return this.dataAbertura;
    }

    /*
     * Atualiza o título do processo
     * @param title novo valor do atributo titulo
     */
    public void setTitulo(P titulo) { 
        this.titulo = titulo;
    }
    /*
     * Recupera o título do processo
     * @return valor do atributo titulo
     */
    public P getTitulo() { 
        return this.titulo;
    }

    /*
     * Atualiza o assunto envolvido no processo
     * @param ass novo valor do atributo assunto
     */
    public void setAssunto(P assunto) { 
        this.assunto = assunto; 
    }
    /*
     * Recupera o assunto envolvido no processo
     * @return valor do atributo assunto
     */
    public P getAssunto() { 
        return this.assunto; 
    }

    @Override
    /*
     * Recupera uma instância de String descrevendo o processo
     * O campo assunto só será descrito pelas subclasses
     * @return descrição do processo
     */
    public String toString() {
        String output;
        output = "Descrição do processo: \n Identificador: "+this.getIdentificador()+", Data de abertura: "+
                this.getDataAbertura()+" e Título: "+this.getTitulo()+".";
        return output;
    }
}

Aguardo uma possivel solucao

Obrigado pela atencao…

DavidUser
public class GravacaoDeObjetos {
    static List<Processo> process = new LinkedList<Processo>();
    public void gravaObj(Processo proce){
        try {
            FileOutputStream f = new FileOutputStream ("C:/Users/fujioka/Documents/NetBeansProjects/GujForunsTest/src/SolucoesETestes/arquivo.arq");
            ObjectOutputStream s = new ObjectOutputStream(f);

            process.add(proce);
            s.writeObject(GravacaoDeObjetos.process);
            s.flush();
            s.close();
            f.flush();
            f.close();
            System.out.println("Gravacao realizada com sucesso!");
        }catch (Exception e){
            System.out.println(e);
        }
    }
    public List<Processo> leObj(){
        List<Processo> lProcess = new LinkedList<Processo>();
        try {
            FileInputStream f = new FileInputStream("C:/Users/fujioka/Documents/NetBeansProjects/GujForunsTest/src/SolucoesETestes/arquivo.arq");
            ObjectInputStream s = new ObjectInputStream(f);
            lProcess = (List<Processo>) s.readObject();
            s.close();
            f.close();

        }catch (Exception e) {
            System.out.println(e);
        }
        return lProcess;
    }
}
DavidUser

Infelizmente, não sei como fazer a gravação dos valores dos objetos em memória para em um arquivo, mas com certeza seriam valores binários ou hexadecimais, precisariam de um interpretador para imbutilas na memória antes da utilização…

kenneth

E ae cara, tranquilo??

Não sei se estou falando besteira, mas se
você quer adicionar ao final do que já está no arquivo,
tente usar append, o que faz com que informações
sejam adicionadas após ao que existe.

Tipo assim:

// o segundo parâmetro indica o uso do append.
FileOutputStream f = new FileOutputStream ("computador.arq",true);

Não sei se é isso que você procura, mas não custa tentar
:stuck_out_tongue:

Abraço!

DavidUser

Exatamente o problema é na hora de pegar os objetos da última list e adicionar na nova para gravação

DavidUser

Se utiliza-se apenas o append ele não teria como fazer referência ao objeto correto.

B

Você quer gravar vários objetos no mesmo arquivo, mas ao ler quer que ele já pegue o objeto certo de primeira?

B

a intencao e fazer uma FILA dinamica…

toda vez q eu for adicionar um objeto a fila… ele grava o msm no arquivo…
dai depois quero recuperar tds os objetos em ordem para refazer a fila…

eu pesava que o .readObject() ia pegando na ordem, mas ele so pega o primeiro…

alguma sugestao glr?!

Obrigado…

B

O readObject pega em ordem, na mesma ordem que foi colocada no arquivo. Se quiser obter o segundo objeto, chame readObject de novo, o terceiro com outro readObject. Isso até ele retornar um null.

B

cara… eu testei isso… ele me retorna o primeiro… quando digito o .readObject a segunda vez ele ja me retorna null

vo tentar quebrar cabeca aqui…

DavidUser
class FileObjectTools{
private static List<Processo> process = new LinkedList<Processo>();
private String arquivo;

    public FileObjectTools(String c){
        this.arquivo = c;
        for(int i = 0; i < leListObj().size(); i++){
            process.add(leListObj().get(i));
        }
    }

    public void gravaObj(Processo proce){
        try {
            FileOutputStream f = new FileOutputStream (arquivo);
            ObjectOutputStream s = new ObjectOutputStream(f);

            process.add(proce);
            s.writeObject(FileObjectTools.process);
            s.flush();
            s.close();
            f.flush();
            f.close();
            System.out.println("Gravacao realizada com sucesso!");
        }catch (Exception e){
            System.out.println(e);
        }
    }
    public List<Processo> leListObj(){
        List<Processo> lProcess = new LinkedList<Processo>();
        try {
            FileInputStream f = new FileInputStream(arquivo);
            ObjectInputStream s = new ObjectInputStream(f);
            lProcess = (List<Processo>) s.readObject();
            s.close();
            f.close();

        }catch (Exception e) {
            System.out.println(e);
        }
        return lProcess;
    }
    static private int cont;
    public Processo leObj(){
        return leListObj().get(cont++);
    }
    public void limpaArq(){
        try{
            FileOutputStream fo = new FileOutputStream(arquivo);
            ObjectOutputStream o = new ObjectOutputStream(fo);
            o.reset();
            process.clear();
        }catch(IOException e){
            System.err.println(e);
        }
    }

}
Ta ai!, exemplo de uso no main:
public static void main (String [] args){
        FileObjectTools f = new FileObjectTools("arquivo.arq");
        
        Processo p2 = new Processo();
        f.gravaObj(p2);

        System.out.printf("Tamanho da List: %02d", f.leObj().size());
        System.out.println( f.leObj.get(0).getIdentificador() );
        System.out.println(f.leObj().getIdentificador());
        System.out.println(f.leObj().getIdentificador());
        System.out.println(f.leObj().getIdentificador());

    }

[color=red]Quero lembrar que os objetos estão em uma List no arquivo[/color]

B

vou ja da uma olhada no que vc fez, mas eu tava pensando aqui e surgiu uma nova duvida…

eu sei gravar no arquivo, mas como e que eu apago um objeto do arquivo? =X

obrigado…

DavidUser

Vou tentar fazer um método pra isso…

E

Isso indica que você precisa de um banco de dados orientado a objetos, ou então de um banco de dados simples mesmo. Gravar um objeto para depois recuperá-lo é uma coisa, mas ficar deletando, modificando etc. objetos já começa a ser algo mais complicado. Uma hora isso acaba constituindo 90% da sua aplicação, o que não é uma boa coisa.

DavidUser

Pronto!
agora criei esse novo método:public boolean nextObj(){ if (cont > leListObj().size()-1) return false; else return true; }
e modifiquei este:

public Processo leObj(){ try{ return leListObj().get(cont++); }catch(Exception e){ return null; } }

e ta ai o seu removedor de Objetos:

public void removeObj (int i){ List<Processo> list = new LinkedList<Processo>(); list = leListObj(); list.remove(i); process = list; try { FileOutputStream f = new FileOutputStream (arquivo); ObjectOutputStream s = new ObjectOutputStream(f); s.writeObject(list); s.flush(); s.close(); f.flush(); f.close(); System.out.println("Remoção realizada com sucesso!"); }catch (Exception e){ System.out.println(e); } }

DavidUser

O que esta agora feito é quase um banco de dados Simples… Não creio que outro fosse mais leve!

Basta as funcionalidades que foram incluidas

O bom vai ser trabalhar com uma biblioteca própia, idependete de conectores, classes externas

DavidUser

Caso queira utilizar realmente como um banco de dados para gravação de objetos, é só substituir o tipo Processo para Object.

DavidUser

encapsulando:

₢public int size(){ return leListObj().size(); }

B

Você reescreve todo o arquivo. Ou deixa os espaços em branco até o arquivo parecer um queijo suiço, e precisar de um reempacotamento (este último não sei te informar como fazer de cabeça).

E David, se eu quisesse obter somente um objeto do arquivo, sem carregar a lista toda, esse teu método não seria muito bom.

DavidUser

Sugestão de melhora?

DavidUser

Seria melhor:
Ir criando diversos arquivos com cada obj,
empacotando toda vez,
e como funcionaria a questão do indíce?

Se fosse mais eficiente que isso, perderia flexibilidade…
Não Acha?

B

Para começar eu já acho meio complicado usar arquivos binários hoje em dia, só o programa que escreveu eles consegue ler, sem falar que não há muita compatibilidade entre diversas versões do mesmo programa. Nestes casos considero arquivos textos melhores.

Tem também que pensar que se o teu programa não for mais trivial como no começo, seria bom já partir para soluções com banco de dados. Até mesmo a versão 6 do Java já vem com um pronto p/ usar (Java DB / Apache Derby).

Respondendo, a maneira seria usar os objetos soltos, sem uma lista para encapsulá-los, como ele já estava fazendo. Guardar em um arquivo por objeto daria um overhead ainda maior, não acho legal.

DavidUser
O problema de usar texo é quando esse banco fabricado, for gravar objetos que foram modificados por várias classes e dependerem das referências.

 O banco que criei é para agir apenas dentro da aplicação, caso o caso fosse uma aplicação de grande porte, seria muito mais eficiênte utilizar de DB's prontos, que possuem lógica mais sofisticada e nesses casos muitas vezes trabalham em linguagem de baixo nível, para dar maior eficiência.

 Nas diversas aplicações comercializaveis de java os objetos são guardados em arquivos bin pois assim é de mais difícil a alteração das lógicas por externos, criandores de séries de bugs.
B

Essa é a pior desculpa para vendor lock-in e falta de segurança/consistência/interoperabilidade do lado da aplicação que já vi. Não é por que o sistema tem um sistema de persistência em arquivos binários que ele vai ser mais seguro, aliás uma mudança/corrupção nos bytes desses arquivos já seria fatal para esse sistema.

DavidUser

Falo da alteração desses bytes para aproveitando para burlar etapas de um sistema ou outros bugs do tipo.

Uma criptografia, sistema “bagunçador de código”, ou codeTrash, usado em um arquivo bin, reduz sua legibilidade e muito, mas mesmo assim opera normal para o sistema.

DavidUser

Aceito a idéia de que o Java não é uma linguagem com eficiêcia quando tratamos de binário…

Para criação desse banco seria melhor utilizar C.

Mas é claro… Só se não quize-se optar por uma classe pré-feita.

B

desculpa a demora pra responder… e que fiquei sem internet…

quanto a usar banco de dados: isso era um trabalho e o uso de arquivo era obrigatorio =D

quanto ao problema: utilizei uma fila de objetos… sempre que eu fazia uma modificacao na fila, eu atualizava o arquivo… (posso explicar melhor se alguem quiser)

obrigados a todos por terem me ajudado, principalmente o David que tiro muitas duvidas e deu bastante atencao ao problema…

Obrigadao!! =D

Brunno.

DavidUser

Posta o code pra vermos como foi ;D

Criado 24 de setembro de 2009
Ultima resposta 30 de set. de 2009
Respostas 30
Participantes 5