opa… estou com uma duvidazinha sobre como gravar objetos em arquivo…
eu criei os seguintes metodos para gravar e ler objetos:
publicvoidgravaObj(Processoproce){try{FileOutputStreamf=newFileOutputStream("computador.arq");ObjectOutputStreams=newObjectOutputStream(f);s.writeObject(proce);s.flush();s.close();f.flush();f.close();System.out.println("Gravacao realizada com sucesso!");}catch(Exceptione){System.out.println(e);}}publicProcessoleObj(){Processopro=newProcesso();try{FileInputStreamf=newFileInputStream("computador.arq");ObjectInputStreams=newObjectInputStream(f);pro=(Processo)s.readObject();s.close();f.close();}catch(Exceptione){System.out.println(e);}returnpro;}
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?!
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
brunnomc
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:
publicclassProcesso<P>implementsSerializable{privatePdataAbertura,titulo,assunto;privatePidentificador;publicProcessonext;/* * Contrutor sem parâmetros - todos os atributos são vazios */publicProcesso(){setIdentificador((P)newInteger(10000));setDataAbertura(null);setTitulo(null);setAssunto(null);}/* * Contrutor com parâmetros - atribuindo novos valores a todos os tributos */publicProcesso(Pidentificador,PdataAbertura,Ptitulo,Passunto){setIdentificador(identificador);setDataAbertura(dataAbertura);setTitulo(titulo);setAssunto(assunto);}/* * Atualiza o identificador do processo * @param id novo valor do atributo identificador */publicvoidsetIdentificador(Pidentificador){if(identificador==null)identificador=(P)newInteger(0);this.identificador=identificador;}/* * Recupera o identificador do processo * @return valor do atributo identificador */publicPgetIdentificador(){returnthis.identificador;}/* * Atualiza a data de abertura do processo * @param data novo valor do atributo dataAbertura */publicvoidsetDataAbertura(PdataAbertura){this.dataAbertura=dataAbertura;}/* * Recupera o identificador do processo * @return valor do atributo identificador */publicPgetDataAbertura(){returnthis.dataAbertura;}/* * Atualiza o título do processo * @param title novo valor do atributo titulo */publicvoidsetTitulo(Ptitulo){this.titulo=titulo;}/* * Recupera o título do processo * @return valor do atributo titulo */publicPgetTitulo(){returnthis.titulo;}/* * Atualiza o assunto envolvido no processo * @param ass novo valor do atributo assunto */publicvoidsetAssunto(Passunto){this.assunto=assunto;}/* * Recupera o assunto envolvido no processo * @return valor do atributo assunto */publicPgetAssunto(){returnthis.assunto;}@Override/* * Recupera uma instância de String descrevendo o processo * O campo assunto só será descrito pelas subclasses * @return descrição do processo */publicStringtoString(){Stringoutput;output="Descrição do processo: \n Identificador: "+this.getIdentificador()+", Data de abertura: "+this.getDataAbertura()+" e Título: "+this.getTitulo()+".";returnoutput;}}
Aguardo uma possivel solucao
Obrigado pela atencao…
DavidUser
publicclassGravacaoDeObjetos{staticList<Processo>process=newLinkedList<Processo>();publicvoidgravaObj(Processoproce){try{FileOutputStreamf=newFileOutputStream("C:/Users/fujioka/Documents/NetBeansProjects/GujForunsTest/src/SolucoesETestes/arquivo.arq");ObjectOutputStreams=newObjectOutputStream(f);process.add(proce);s.writeObject(GravacaoDeObjetos.process);s.flush();s.close();f.flush();f.close();System.out.println("Gravacao realizada com sucesso!");}catch(Exceptione){System.out.println(e);}}publicList<Processo>leObj(){List<Processo>lProcess=newLinkedList<Processo>();try{FileInputStreamf=newFileInputStream("C:/Users/fujioka/Documents/NetBeansProjects/GujForunsTest/src/SolucoesETestes/arquivo.arq");ObjectInputStreams=newObjectInputStream(f);lProcess=(List<Processo>)s.readObject();s.close();f.close();}catch(Exceptione){System.out.println(e);}returnlProcess;}}
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.FileOutputStreamf=newFileOutputStream("computador.arq",true);
Não sei se é isso que você procura, mas não custa tentar
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
Bruno_Laturner
Você quer gravar vários objetos no mesmo arquivo, mas ao ler quer que ele já pegue o objeto certo de primeira?
B
brunnomc
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
Bruno_Laturner
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
brunnomc
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
classFileObjectTools{privatestaticList<Processo>process=newLinkedList<Processo>();privateStringarquivo;publicFileObjectTools(Stringc){this.arquivo=c;for(inti=0;i<leListObj().size();i++){process.add(leListObj().get(i));}}publicvoidgravaObj(Processoproce){try{FileOutputStreamf=newFileOutputStream(arquivo);ObjectOutputStreams=newObjectOutputStream(f);process.add(proce);s.writeObject(FileObjectTools.process);s.flush();s.close();f.flush();f.close();System.out.println("Gravacao realizada com sucesso!");}catch(Exceptione){System.out.println(e);}}publicList<Processo>leListObj(){List<Processo>lProcess=newLinkedList<Processo>();try{FileInputStreamf=newFileInputStream(arquivo);ObjectInputStreams=newObjectInputStream(f);lProcess=(List<Processo>)s.readObject();s.close();f.close();}catch(Exceptione){System.out.println(e);}returnlProcess;}staticprivateintcont;publicProcessoleObj(){returnleListObj().get(cont++);}publicvoidlimpaArq(){try{FileOutputStreamfo=newFileOutputStream(arquivo);ObjectOutputStreamo=newObjectOutputStream(fo);o.reset();process.clear();}catch(IOExceptione){System.err.println(e);}}}
Ta ai!,
exemplo de uso no main:
publicstaticvoidmain(String[]args){FileObjectToolsf=newFileObjectTools("arquivo.arq");Processop2=newProcesso();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
brunnomc
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
enantiomero
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
Bruno_Laturner
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
Bruno_Laturner
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
Oproblemadeusartexoéquandoessebancofabricado,forgravarobjetosqueforammodificadosporváriasclassesedependeremdasreferências.Obancoquecrieiéparaagirapenasdentrodaaplicação,casoocasofosseumaaplicaçãodegrandeporte,seriamuitomaiseficiênteutilizardeDB'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.Nasdiversasaplicaçõescomercializaveisdejavaosobjetossãoguardadosemarquivosbinpoisassimédemaisdifícilaalteraçãodaslógicasporexternos,criandoresdesériesdebugs.
B
Bruno_Laturner
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
brunnomc
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…