Java FileInputStream ObjectInputStream atinge o final do arquivo EOF

Eu estou tentando ler o número de linha em um arquivo binário usando readObject, mas recebo IOException EOF. Estou fazendo o caminho certo?

FileInputStream istream = new FileInputStream(fileName); ObjectInputStream ois = new ObjectInputStream(istream); /** calculate number of items **/ int line_count = 0; while( (String)ois.readObject() != null){ line_count++; } 

readObject() não retorna null em EOF. Você poderia pegar o EOFException e interpretá-lo como EOF, mas isso não conseguiria distinguir um EOF normal de um arquivo que foi truncado.

Uma abordagem melhor seria usar alguns metadados. Ou seja, em vez de perguntar ao ObjectInput quantos objects estão no stream, você deve armazenar a contagem em algum lugar. Por exemplo, você pode criar uma class de metadados que registre a contagem e outros metadados e armazene uma instância como o primeiro object em cada arquivo. Ou você pode criar uma class de marcador EOF especial e armazenar uma instância como o último object em cada arquivo.

Eu tive o mesmo problema hoje. Embora a questão seja bastante antiga, o problema permanece e não houve solução limpa fornecida. Ignorando EOFException deve ser evitado, pois pode ser lançado quando algum object não foi salvo corretamente. Escrever null obviamente impede que você use valores nulos para qualquer outra finalidade. Finalmente, usar available() no stream de objects sempre retorna zero, pois o número de objects é desconhecido.

Minha solução é bem simples. ObjectInputStream é apenas um wrapper para algum outro stream, como FileInputStream. Embora ObjectInputStream.available () retorne zero, o FileInputStream.available retornará algum valor.

  FileInputStream istream = new FileInputStream(fileName); ObjectInputStream ois = new ObjectInputStream(istream); /** calculate number of items **/ int line_count = 0; while( istream.available() > 0) // check if the file stream is at the end { (String)ois.readObject(); // read from the object stream, // which wraps the file stream line_count++; } 

Não. Capture EOFException e use isso para finalizar o loop.

É curioso que a API não forneça uma solução mais elegante para isso. Eu acho que o EOFException iria funcionar, mas eu sempre fui encorajado a ver exceções como events inesperados, enquanto aqui você costumava esperar que o stream de object para chegar ao fim.

Eu tentei contornar isso escrevendo um tipo de object “marker” para significar o final do stream de object:

 import java.io.Serializable; public enum ObjectStreamStatus implements Serializable { EOF } 

Então, no código que está lendo o object, verifiquei este object EOF no loop de leitura de objects.

Não, você precisa saber quantos objects existem no arquivo binário. Você poderia escrever o número de objects no início do arquivo (usando writeInt por exemplo) e lê-lo enquanto o carrega.

Outra opção é chamar ois.available () e loop até que ele retorne 0. No entanto, não tenho certeza se isso é 100% de certeza.

Parece que o problema está nos dados que você escreveu. Supondo que os dados estão escritos como esperado por este código, não deve haver um problema.

(Eu vejo que você está lendo String s. Este ObectInputStream não é para ler arquivos de texto. Use InputStreamReader e BufferedReader.readLine para isso. Da mesma forma, se você tiver escrito o arquivo com DataOutputSteam.writeUTF , leia-o com DataInputStream.readUTF )

O método disponível de ObjectInputStream não pode ser usado para finalizar o loop, pois ele retorna 0 mesmo se houver objects a serem lidos em um arquivo. Escrever um nulo em um arquivo não parece ser uma boa solução, pois os objects podem ser nulos, o que seria interpretado como o final do arquivo. Acho que capturar a EOFException para finalizar os loops é uma prática melhor, pois se EOFException ocorrer (seja porque você chegou ao final do arquivo ou por algum outro motivo), você terá que terminar o loop de qualquer maneira.

Se você escrever um object nulo no final do arquivo, quando você o ler de volta, você obterá um valor nulo e poderá terminar seu loop.

Apenas adicione: out.writeObject (null);

quando você serializar os dados.

A melhor maneira possível de terminar o loop pode ser feita adicionando um object nulo no final. Enquanto lê o object nulo pode ser usado como uma condição de contorno para sair do loop. Capturar o EOFException também resolve o objective, mas são necessários poucos m