Random Access File de Objetos

Pessoal…estou precisando fazer um trabalho sobre acesso em arquivos e me deparei com um problema.
Eu preciso gravar objetos num arquivo de acesso aleatório e depois ler esses objetos numa posição qualquer, ou seja, por exemplo: gravar 10 objetos carros num arquivo e depois ler o objeto carro da posição X para carregá-lo na memória e trabalhar com ele.
Eu serializei os objetos que eu queria gravar…e utilizei o metodo write(byte[]) do RandomAccessFile pra gravar os objetos. Até ai tudo bem…tinha gravado…mas na hora de ler tentei usar o read(byte[]) mas tá dando exception.
Aqui vai o código e o erro…
Erro: invalid stream header

     public static byte[] getBytes(Object obj) throws java.io.IOException, Exception{
            try{
              ByteArrayOutputStream bos = new ByteArrayOutputStream();
              ObjectOutputStream oos = new ObjectOutputStream(bos);
              oos.writeObject(obj);
              oos.flush();
              oos.close();
              bos.close();
              byte [] data = bos.toByteArray();
              return data;
            }
            catch(IOException e){
                    throw new Exception("Erro ao converter objeto.");
            }
    }

    public static int tamanho(Object obj) throws java.io.IOException, Exception {
            return     getBytes(obj).length;
    }
	
    public static Object readFile(String nameFile, String typeFile, int pos) throws Exception {
        Object obj = null;
        try {
            raf = new RandomAccessFile(new File(String.format("%s.%s", nameFile, typeFile)), "rw");
            raf.seek(pos - 1);
            byte[] arrayObjeto = new byte[tamanho(obj)];
            raf.read(arrayObjeto);
            ByteArrayInputStream bis = new ByteArrayInputStream(arrayObjeto);
            ObjectInputStream ois = new ObjectInputStream(bis); //Nessa linha o erro!!
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException e) {
            throw new Exception("Erro ao ler arquivo.");
        }
        return obj;
    }

se alguém puder ajudar com alguma idéia de como fazer, agradeço antecipadamente.

Faça desse jeito ai que vai funcionar filet!

public static void main(String[] args) {
		
		File f = new File("carros.txt");
		Carro c1 = new Carro("Gol", "vermelho");
		
		try {
			
			f.delete();
			f.createNewFile();
			
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
			
			out.writeObject(c1);
			out.flush();
			out.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		c1.setModelo("Palio");
		
		try {
			
			ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
			
			Carro c2 = (Carro) in.readObject();
			
			System.out.println(c2.getModelo()); // prints Gol
			
			in.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

Qualquer coisa perguntaê!

Thiagoh…desse modo o acesso aos objetos seria sequencial neh n?
Eu tava querendo que tivesse um acesso direto em posições do arquivo…
Por exemplo,na tabela abaixo os números em vermelhos seriam as posições no arquivo e cada linha correspoderia a um objeto livro:

Dessa forma, como estou prevendo que o arquivo vai ser muito grande na minha aplicação, o acesso não poderia ser sequencial, pq nesse caso para ler o objeto 12 teria que ler primerio os objetos do 1 até o 11.
O única classe de IO do java que vi que tem método de posicionamento de ponteiro em arquivo foi RandomAccessFile onde tem o método seek(int pos) massssssssssss, a RandomAccessFIle só tem métodos de escrita e leitura de tipos primitivos ou array de bytes, sem método para gravar ou ler objetos.

Se tem uma forma de implementar isso em java…infelizmente ainda desconheço.
Se naum tem…Java como uma linguagem “poderosa” que eh deveria implementar isso.

Uma forma meio nojenta de fazer isso é criar um pequeno “filesystem” dentro do seu arquivo, contendo um diretório de objetos. Dessa forma, quando você precisasse acessar um objeto, teria de primeiramente achar o objeto no diretório (associando-lhe um nome, talvez), que lhe diria a posição binária onde o objeto está no arquivo.
É dessa forma que um arquivo binário do Microsoft Word ou Excel funciona - o editor grava objetos no arquivo, e esses objetos são acessados por um diretório. Procure pela documentação de “OLE Compound Document Format” para ver como é que o Word faz isso.
Quando o Word precisa remover um objeto (como uma figura), ele deixa um “buraco” no arquivo - se você desativar a tal da “gravação rápida”, ele então carrega todos os objetos e os grava todos de uma vez, sequencialmente, para evitar tais buracos.
Achou tudo muito complicado? Então use um banco de dados orientado a objetos mesmo, que eles tomam conta dessas coisas por você.

Ok meu caro!

resolvido seu problema!

Veja o Código abaixo!! ;pp


	public static void main(String[] args) {
		
		File f = new File("carros.txt");
		Carro c1 = new Carro("Gol", "vermelho");
		RandomAccessFile raf = null;
		int objSize = 0;
		
		try {
			
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			
			ObjectOutputStream out = new ObjectOutputStream(bos) ;
	        out.writeObject(c1);
	        out.close();
	        
	        f.delete();
	        f.createNewFile();	        
	        
	        raf = new RandomAccessFile(f, "rw");
	        raf.seek(13); // posição de escrita
	        objSize = bos.toByteArray().length;
	        raf.write(bos.toByteArray());
	        raf.close();
	        
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		c1.setModelo("Palio");
		
		try {
			
			byte[] obj = new byte[objSize];
			
			raf = new RandomAccessFile(f, "r");
			raf.seek(13); // posição de leitura
			raf.read(obj);
			raf.close();
			
			ByteArrayInputStream bis = new ByteArrayInputStream(obj);
			ObjectInputStream in = new ObjectInputStream(bis);
			
			Carro c2 = (Carro) in.readObject();
			
			System.out.println(c2.getModelo()); // prints Gol
			
			in.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

Agora voce tem escrita e leitura em posição específica.
Note que eu escrevo na posição 13 e depois leio na posição 13. Se voce mudar uma das duas posições e elas ficarem diferentes e a maquina virtual nao encontrar o seu objeto na posicao especificada ocorre uma java.io.StreamCorruptedException: invalid stream header.

;pp