Streaming de arquivos em Java

Atualmente, estou desenvolvendo aplicativos gráficos 3D usandoJOGL (Ligação Java OpenGL). Em resumo, tenho um enorme arquivo binário de paisagem. Devido ao seu tamanho, eu tenho que transmitir pedaços de terreno no tempo de execução. Portanto, vemos explicitamente a preocupação com o acesso aleatório. Eu já terminei a primeira implementação (e suja :)) (talvez seja multiencadeada), onde estou usando uma abordagem tola ... Aqui está a inicialização dela:

dataInputStream = new DataInputStream(new BufferedInputStream(fileInputStream,4 * 1024);
dataInputStream.mark(dataInputStream.available());

E quando eu preciso ler (transmitir) um pedaço especial (eu já sei o seu "deslocamento" no arquivo), estou executando o seguinte (vergonha para mim :)):

dataInputStream.reset();
dataInputStream.skipBytes(offset);
dataInputStream.read(whatever I need...);

Desde que tive pouca experiência, essa foi a primeira coisa que pude pensar :) Então, até agora, li 3 artigos úteis e bastante interessantes (estou sugerindo que você os leia, talvez se você estiver interessado neste tópico)

Buffers de bytes e memória não heap - Gregory parece ser alfabetizado em Java NIO.

Dica Java: Como ler arquivos rapidamente [http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly] - Essa é uma referência interessante.

Artigos: Ajustando o desempenho de E / S do Java [http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/] - Recomendações simples da Sun, mas role para baixo e dê uma olhada na seção "Acesso aleatório"; eles mostram uma implementação simples do RandomAccessFile (RAF) com aprimoramento de buffer automático.

Gregory fornece vários arquivos * .java no final de seu artigo. Um deles é um benchmarking entre o FileChannel + ByteBuffer + Mapping (FBM) e o RAF. Ele diz que notou uma aceleração de 4x ao usar o FBM em comparação com o RAF. Eu executei esse benchmark nas seguintes condições:

O deslocamento (por exemplo, local de acesso) é gerado aleatoriamente (no escopo do arquivo, por exemplo, 0 - file.length ());O tamanho do arquivo é 220MB;1 000 000 acessos (75% leituras e 25% gravações)

Os resultados foram impressionantes:

~ 28 seg para RAF!~ 0,2 segundos para FBM!

No entanto, sua implementação do RAF neste benchmark não possui buffer automático (o terceiro artigo fala sobre um), então acho que é a chamada do método "RandomAccessFile.seek", que diminui o desempenho tanto.

Ok, agora depois de todas essas coisas que aprendi, há uma pergunta e um dilema :)

Pergunta, questão: Quando estamos mapeando um arquivo usando "FileChannel.map", o Java copia todo o conteúdo do arquivo no MappedByteBuffer? Ou apenas imita? Se ele copiar, o uso da abordagem FBM não é adequado para a minha situação, é?

Dilema: Depende das suas respostas sobre a pergunta ...

Se o mapeamento copia um arquivo, parece que tenho apenas 2 soluções possíveis:RAF + com buffer próprio (aquele do terceiro artigo) oufaça uso da posição no FileChannel (não com mapeamento) ... Qual seria o melhor?

Se o mapeamento não copiar um arquivo, tenho 3 opções: duas anteriores eO próprio FBM.

Editar: Aqui está mais uma pergunta. Alguns de vocês aqui dizem que o mapeamento não copia o arquivo no MappedByteBuffer. Ok, então, por que não consigo mapear um arquivo de 1 GB, estou recebendo a mensagem "falha ao mapear" ...

P. S. Gostaria de receber uma resposta satisfatória com conselhos, pois não consigo encontrar informações consistentes sobre esse tópico na Internet.

Obrigado :)

questionAnswers(3)

yourAnswerToTheQuestion