Guardar dados em ficheiro binário no java (equivalente no java à função fwrite e fread do C)

Sou inexperiente em java, pois estou a fazer o meu primeiro projecto em java, e gostaria de saber quais são os metodos equivalentes em java correspondentes às funções fwrite e fread do C.
Implemetei a Classe Pacientes e, para para cada novo paciente, queria guardar num ficheiro .dat, função que em C corresponde a fwrite.
Até agora desenvolvi o seguinte códico em java:
static void registarPaciente() {
String ficheiro=“HL7.dat”;
int id=6;
ADT a = leDadosPaciente(id);
a.PAC.id=id;
try {
FileOutputStream fi =new FileOutputStream(ficheiro);
ObjectOutputStream paci = new ObjectOutputStream(fi);
paci.writeObject(a);
paci.close();
}
catch (Exception e) {
e.printStackTrace();
}

Como dá para ver, cada novo registo de um paciente é escrito por cima do anterior apagando o anterior. Gostaria de guardar todos os pacientes no mesmo ficheiro e depois ter acesso a eles, tal como fazia em C atraves da função fwrite e fread.

Alguem me consegue resolver o meu problema, o mais breve possivel?

Muito Obrigado :smiley:

Vê se java.io.RandomAccessFile não resolve seu problema.

Antes de mais obrigado por teres respondido a minha mensagem. :slight_smile:

Desculpa a minha ignorancia, mas podias-me dar uma ajuda para entender a classe RandomAccessFile, e como a poderei utilizar para guardar e aceder aos dados que quero armazenar?

Como referi anteriormente, tenho a classe Paciente com vários objectos, que no meu anterior programa em C correspondia a uma Struct de dados, e quero registar varios pacientes e guarda-los em um ficheiro .dat. Como posso guarda-los atraves da Classe RandomAcessFile.

Obrigado pela atenção :smiley:

[quote=Tiago Correia] Antes de mais obrigado por teres respondido a minha mensagem. :slight_smile:

Desculpa a minha ignorancia, mas podias-me dar uma ajuda para entender a classe RandomAccessFile, e como a poderei utilizar para guardar e aceder aos dados que quero armazenar?

Como referi anteriormente, tenho a classe Paciente com vários objectos, que no meu anterior programa em C correspondia a uma Struct de dados, e quero registar varios pacientes e guarda-los em um ficheiro .dat. Como posso guarda-los atraves da Classe RandomAcessFile.

Obrigado pela atenção :smiley:
[/quote]

Na verdade não sei direito usar essa classe. A utilizei em um problema semelhante ao seu em 2003 e funcionou muito bem. Mas isso foi há cinco anos atrás.

Uma forma de instanciar um RandomAccessFile e de como escrever nele:

package exemplos;

import java.io.RandomAccessFile;

public class Teste {

	public Teste(){
		try {
			//Abre o arquivo HL7.dat para read/write
			RandomAccessFile ra = new RandomAccessFile("HL7.dat", "rw");
			
			//Escreve um vetor de bytes no arquivo
			byte b[] = new byte[2];
			ra.write(b);
			
			//Escreve uma String no arquivo
			String s = new String();
			ra.writeChars(s);
			ra.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		new Teste();
	}
}

Se vc estiver usando uma ide pode escrever “ra.” e dar um ctrl+espaço para ver os métodos disponiveis do randomAccessFile.
Vi que no seu código vc quer escrever um vários objeto em um arquivo, isso só vai ser possível se:
**Vc fizer vários arquivos e em cada arquivo escrever um objeto.
**Vc Usar o RandomAccessFile e usar uma estrutura de escrite e leitura tipo
Classe Paciente
String nome
int idade

Escreve no arquivo um String sendo o nome do primeiro paciente e depois um int como idade, depois um String como nome do segundo paciente e assim por diante…

Tava a pensar Criar uma classe arquivo ou ficheiro em que guarda-la lá todos os dados e os podia aceder lá. Nessa classe teria de importar a calsse java.io.RandomAccessFile e criava o objecto arquivo e metodos para poder criar e aceder aos dados.
Contudo tenho várias duvidas…
Pelo que me parece na classe RandomAccessFile os seus metodos tem como argumentos de entrada strings, e eu quero guardar no arquivo a classe Pacientes que é o equivalente a struct em C(como tenho no programa de C). não percebi ainda como se faz adicionar dados ao fim do arquivo e não por cima dos dados tal como no exemplo que demostrei. sei que trabalhando em um ficheiro txt basta fazer “FileWriter fstream =new FileWriter(ficheiro_1, true)”, mas como quero trabalhar com ficheiros binários não posso usar esse metodo.

que axas que devo fazer?

desculpa se estou a dizer asneiras, mas os meus conhecimentos ainda são muito rudimentares

Obrigado pela atenção

Abraço :smiley:

de uma olhada no link abaixo, o que vc quer fazer a apendar um texto no final do arquivo

http://www.exampledepot.com/egs/java.io/AppendToFile.html

quanto a salvar a objeto em um arquivo é possivel, porem quando se trabalha com java é preferivel usar um banco de dados, como mysql, postgres por exemplo

O meu problema é mesmo guardar uma Classe formada por vários tipos de objectos. Eu sei que existe a possibilidade de fazer a ligação com um banco de dados ou em formato xml, contudo o objectivo é mesmo guardar um ficheiro binário. No meu caso a tenho a superclasse ADT que é constituida por outras classes de dados(informações do paciente, médico, etc) constituida por vários objectos. por cada novo paciente vou preencher os objectos das varias classes e vou guarda-los e acrescenta-los ao ficheiro binário. O problema reside na maneira como vou guardar as informações dos vários pacientes e depois como vou aceder a elas.
Neste momento consigo guardar só um paciente (ADT), quando registo outro ele guarda-o mas apaga o anterior
Não consigo resolver este problema.
Parece-me que o problema dos metodos da classe RandomAccessFile é que não permitem guardar os dados estruturados das classes de objectos, enquanto os metods FileOutputStream fos =new FileOutputStream(ficheiro) e ObjectOutputStream oos = new ObjectOutputStream(fos) o permitem mas não permite o acrescentar ao ficheiro.

Além consegue resolver este problema…

Obrigado pela atenção :smiley:

Abraço

Olha ai amigo, da uma olhada se isso aqui ajuda

é amigo, não tem como escrever vários objetos em um arquivo.

Ou vc cria vários arquivos com um objeto cada um, ou vc coloca todos os seus pacientes em um vetor ou List e escreve esse vetor no arquivo ou vc usa randomAccessFile e escreve atributo por atributo no arquivo. Uma forma legal seria usa ArrayList exemplo:

package exemplos;

import java.io.Serializable;

public class Paciente implements Serializable {
	
	private String nome;
	private int idade;
	
	public Paciente(String nome, int idade) {
		this.nome = nome;
		this.idade = idade;
	}
	
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public int getIdade() {
		return idade;
	}
	public void setIdade(int idade) {
		this.idade = idade;
	}
}
package exemplos;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class Testando {
	
	public void escrever() throws Exception{
		ArrayList<Paciente> pacientes = new ArrayList<Paciente>();
		pacientes.add(new Paciente("joão", 10));
		pacientes.add(new Paciente("maria", 30));

		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("arquivo.dat"));
		out.writeObject(pacientes);
		out.flush();
		out.close();
	}
	
	public void ler() throws Exception{
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("arquivo.dat"));
		ArrayList<Paciente> pacientes = (ArrayList<Paciente>)in.readObject();
		in.close();

		for(Paciente p:pacientes){
			System.out.println("Nome: " + p.getNome());
			System.out.println("Idade: " + p.getIdade());
		}
	}
	
	public static void main(String[] args) {
		Testando t = new Testando();
		try {
			t.escrever();
			t.ler();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

[quote=ivo costa]é amigo, não tem como escrever vários objetos em um arquivo.

Ou vc cria vários arquivos com um objeto cada um, ou vc coloca todos os seus pacientes em um vetor ou List e escreve esse vetor no arquivo ou vc usa randomAccessFile e escreve atributo por atributo no arquivo. Uma forma legal seria usa ArrayList exemplo:

package exemplos;

import java.io.Serializable;

public class Paciente implements Serializable {
	
	private String nome;
	private int idade;
	
	public Paciente(String nome, int idade) {
		this.nome = nome;
		this.idade = idade;
	}
	
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public int getIdade() {
		return idade;
	}
	public void setIdade(int idade) {
		this.idade = idade;
	}
}
package exemplos;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class Testando {
	
	public void escrever() throws Exception{
		ArrayList<Paciente> pacientes = new ArrayList<Paciente>();
		pacientes.add(new Paciente("joão", 10));
		pacientes.add(new Paciente("maria", 30));

		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("arquivo.dat"));
		out.writeObject(pacientes);
	}
	
	public void ler() throws Exception{
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("arquivo.dat"));
		ArrayList<Paciente> pacientes = (ArrayList<Paciente>)in.readObject();

		for(Paciente p:pacientes){
			System.out.println("Nome: " + p.getNome());
			System.out.println("Idade: " + p.getIdade());
		}
	}
	
	public static void main(String[] args) {
		Testando t = new Testando();
		try {
			t.escrever();
			t.ler();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

[/quote]

hehehe, ontem eu dei um exemplo bem parecido de como fazer isso e todo mundo já veio esculachando.
http://www.guj.com.br/posts/list/15/95486.java#511813

é que no teu caso, a guria não postou nenhuma linha de código, e foi logo dizendo que queria o trabalho pronto.

O cara ai de cima pelo menos colocou umas linhas de código, e eu não coloquei tudo, dei apenas um exemplo pra ele. :smiley:

Ola cara :slight_smile:

Existe algum método que dê para obter o comprimento de um objecto?? O meu objecto é a classe ADT, ou seja quero saber o comprimento da classe ADT.

obrigado a todos pela atenção prestada:D

Amigo, acho que você vai ter de aprender serialização. Em Java não é possível obter diretamente o “tamanho” de um objeto, mas é possível serializar um objeto para um array de bytes, e obter o tamanho desse array serializado.

Estude ObjectOutputStream e ByteArrayOutputStream.

Como assim comprimento de um objeto?

para pegar o tamanho de uma List use:

list.size();

para pegar o tamanho de um vetor use

vetor.length;

para saber o tamanho que um objeto do tipo Aluno iria ocupar em disco some o tamanho de cada atributo, por exemplo:
String nome - 2 bytes para cada caracter no nome “maria” ocuparia 10 bytes
int idade - 4 bytes
double - 8 bytes
“procure o resto no google”

Ola a todos :slight_smile:

Para escrever o objecto que é a classe ADT fiz a seguinte linha de código

[code]static void registarPaciente1() {

	String ficheiro="HL7.dat";
	int id=6;
	ADT a = leDadosPaciente(id);
               a.PAC.id=id;
	//	Vector<ADT> pacientes = new Vector<ADT>();
	try {
	//pacientes.add(pacientes);
	                FileOutputStream fos =new FileOutputStream(ficheiro, true);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(a);
		oos.close();
		}			
	catch (Exception e) {
		e.printStackTrace();  
	}
	
	
	geral.limparEcra();
	
}[/code]

Tá a escrever como eu queria.
Agora o problema está na leitura. como eu tenho vários registos ADT no mesmo ficheiro binário(atendendo ao append), eu para ter acesso a cada um deles tava a pensar criar um ciclo for e que para o incremento precisava de saber o tamanha de cada objecto. Mas aqui surge o problema que os objectos ADT variam de tamanho, logo não posso ir por aqui.

Com o código que desenvolvi ate agora só tenho acesso ao primeiro registo que guardei no ficheiro.
Que posso eu fazer para ter acesso aos outros registos. uma possibilidade era atraves da função seek da java.io.RandomAccessFile .
codigo de leitura

Abraço :smiley:

[code] static void listarPaciente() {

	ADT a;
	String ficheiro="HL7.dat";
	int c=length(a);

	try {
		FileInputStream fis = new FileInputStream(ficheiro);
		ObjectInputStream ois = new ObjectInputStream(fis);
  		a = (ADT) ois.readObject();
		apresentardados(a);
		ois.close();
		
		}
	catch (Exception e) { e.printStackTrace();
		}
	
	
}[/code]

Ola a todos :slight_smile:

quando faço um appending para a classe ADT ele guarda-me numa nova linha no ficheiro binário?

abraço :smiley:

Companheiro, vou tentar mais uma vez:

*vc NÃO pode escrever vários objetos no mesmo arquivo, pq um vai sobrescrever o outro, isso que vc está tentando fazer só irá funcionar para o último objeto. Se vc deseja escrever vários objetos em um arquivo use o RandomAccessFile e escreva atributo a atributo ou coloque todos os seus objetos em um vetor e escreva o vetor.

Ola :slight_smile:
Eu tou a conseguir escrever no mesmo ficheiro binário vários objectos atraves da função e já confirmei isso:
FileOutputStream fos =new FileOutputStream(ficheiro, true);
o problema é agora posicionar e selecionar o objecto que quero.

quando leio um objecto ele só me lê o primeiro…

obrigado pela atenção prestada

Uma base de dados no teu caso iria bem :stuck_out_tongue:

Usa o JFileHelpers! Com ele vc faz isto facinho facinho…

http://www.jfilehelpers.com/index_pt.php

E pelo que vi vc não precisa gerar um arquivo binário, pode muito bem ser um arquivo texto, e para isto vc poderia também gerar os arquivos em XML!

http://www.guj.com.br/java.tutorial.artigo.118.1.guj

http://www.guj.com.br/java.tutorial.artigo.19.1.guj

Mas o JFileHelpers resolve todos os teus problemas…