Pergunta

O Documentação da Sun para DataInput.skipBytes afirma que "faz uma tentativa de pular n bytes de dados do fluxo de entrada, descartando os bytes ignorados.No entanto, pode pular um número menor de bytes, possivelmente zero.Isto pode resultar de uma série de condições;chegar ao final do arquivo antes que n bytes tenham sido ignorados é apenas uma possibilidade."

  1. Além de chegar ao final do arquivo, por que skipBytes() não pular o número certo de bytes?(O DataInputStream que estou usando, vou embrulhar um FileInputStream ou um PipedInputStream.)

  2. Se eu definitivamente quiser pular n bytes e lançar um EOFException se isso me faz ir para o final do arquivo, devo usar readFully() e ignorar a matriz de bytes resultante?Ou há um jeito melhor?

Foi útil?

Solução

1) Pode não haver tantos dados disponíveis para leitura (a outra extremidade do canal pode não ter enviado tantos dados ainda) e a classe de implementação pode não ser bloqueadora (ou seja,ele apenas retornará o que puder, em vez de esperar por dados suficientes para atender à solicitação).

Não sei se alguma implementação realmente se comporta dessa maneira, mas a interface foi projetada para permitir isso.

Outra opção é simplesmente que o arquivo seja fechado no meio da leitura.

2) ReadFully() (que sempre esperará por entrada suficiente ou falhará) ou chamará skipBytes() em um loop.Acho que o primeiro é provavelmente melhor, a menos que o conjunto seja realmente vasto.

Outras dicas

Me deparei com esse problema hoje.Ele estava lendo uma conexão de rede em uma máquina virtual, então imagino que possa haver vários motivos para isso acontecer.Eu resolvi isso simplesmente forçando o fluxo de entrada a pular bytes até que ele pulasse o número de bytes que eu queria:

int byteOffsetX = someNumber; //n bytes to skip
int nSkipped = 0;

nSkipped = in.skipBytes(byteOffsetX);
while (nSkipped < byteOffsetX) {
    nSkipped = nSkipped + in.skipBytes(byteOffsetX - nSkipped);
}

Josh Bloch divulgou isso recentemente.É consistente porque não é garantido que InputStream.read leia tantos bytes quanto possível.No entanto, é totalmente inútil como método de API.InputStream provavelmente também deveria ter readFully.

Acontece que readFully() adiciona mais sobrecarga de desempenho do que eu estava disposto a suportar.

No final eu comprometi:Eu chamo skipBytes() uma vez e, se retornar menos que o número correto de bytes, chamo readFully() para os bytes restantes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top