Qual é a utilidade do ByteBuffer em Java? [fechadas]

199

Quais são os aplicativos de exemplo para a ByteBufferem Java? Por favor, liste todos os cenários de exemplo onde isso é usado. Obrigado!

Aklin
fonte
1
A compactação do Apache Hadoop (codec zlib, por exemplo) usa o ByteBuffer de jave.nio.
Nikk
Bom para enviar dados para GPUs.
Pixel

Respostas:

138

Esta é uma boa descrição de seus usos e deficiências. Você o utiliza essencialmente sempre que precisa executar E / S rápida e de baixo nível. Se você fosse implementar um protocolo TCP / IP ou se estivesse escrevendo um banco de dados (DBMS), essa classe seria útil.

kelloti
fonte
3
É útil em um site de alto tráfego desenvolvido usando Java & Cassandra DB?
Aklin
1
Após uma pesquisa rápida, parece que sim, Cassandra usa ByteBuffer: mail-archive.com/[email protected]/msg14967.html Se você está se perguntando sobre um site, pode haver, mas normalmente é apenas vai ser usado por sites indiretamente - usando ferramentas como Cassandra
kelloti
1
não é um link ruim, obrigado. gostaria de adicionar este que eu achei útil - worldmodscode.wordpress.com/2012/12/14/…
Peter Perháč
Link ruim eu estou com medo ...
RoyalBigMack 14/06
96

A classe ByteBuffer é importante porque forma uma base para o uso de canais em Java. A classe ByteBuffer define seis categorias de operações em buffers de byte, conforme declarado na documentação do Java 7 :

  • Métodos absolutos e relativos de obtenção e colocação que lêem e escrevem bytes únicos;

  • Os métodos de obtenção em massa relativa que transferem seqüências contíguas de bytes desse buffer para uma matriz;

  • Métodos de colocação em massa relativa que transferem seqüências contíguas de bytes de uma matriz de bytes ou de outro buffer de bytes para esse buffer;

  • Métodos absolutos e relativos de obtenção e colocação que lêem e gravam valores de outros tipos primitivos, convertendo-os para e a partir de seqüências de bytes em uma ordem de bytes específica;

  • Métodos para criar buffers de exibição, que permitem que um buffer de bytes seja visualizado como um buffer contendo valores de algum outro tipo primitivo; e

  • Métodos para compactar , duplicar e fatiar um buffer de bytes.

Example code : Putting Bytes into a buffer.

    // Create an empty ByteBuffer with a 10 byte capacity
    ByteBuffer bbuf = ByteBuffer.allocate(10);

    // Get the buffer's capacity
    int capacity = bbuf.capacity(); // 10

    // Use the absolute put(int, byte).
    // This method does not affect the position.
    bbuf.put(0, (byte)0xFF); // position=0

    // Set the position
    bbuf.position(5);

    // Use the relative put(byte)
    bbuf.put((byte)0xFF);

    // Get the new position
    int pos = bbuf.position(); // 6

    // Get remaining byte count
    int rem = bbuf.remaining(); // 4

    // Set the limit
    bbuf.limit(7); // remaining=1

    // This convenience method sets the position to 0
    bbuf.rewind(); // remaining=7
ykombinator
fonte
56
a maior parte deste comentário é copiada dos documentos do java 7 .
Janus Troelsen
6
A menos que você esteja tirando proveito de um efeito colateral não óbvio, acredito que você possa estar usando o método errado para a colocação absoluta. O Javadoc parece indicar que a venda absoluta requer um valor de índice.
Chuck Wolber
6
mesmo que seja apenas uma cópia do documento da API, ele deve ter sua pontuação, mas algumas pessoas parecem ter preguiça de vê-lo.
1028 Chris
1
Há um erro em um dos exemplos. O "absoluto put", perde o primeiro parâmetro que representa o índice (0 neste caso).
bvdb
21

O Java IO usando APIs orientadas a fluxo é realizado usando um buffer como armazenamento temporário de dados no espaço do usuário. Os dados lidos do disco pelo DMA são primeiro copiados para buffers no espaço do kernel, que são transferidos para o buffer no espaço do usuário. Portanto, há sobrecarga. Evitá-lo pode obter um ganho considerável no desempenho.

Poderíamos pular esse buffer temporário no espaço do usuário, se houvesse uma maneira direta de acessar o buffer no espaço do kernel. O Java NIO fornece uma maneira de fazer isso.

ByteBufferestá entre os vários buffers fornecidos pelo Java NIO. É apenas um contêiner ou tanque de retenção para ler ou gravar dados. O comportamento acima é alcançado alocando um buffer direto usando a allocateDirect()API no buffer.

A documentação do Byte Buffer em Java tem informações úteis.

deepujain
fonte
14

No Android, você pode criar um buffer compartilhado entre C ++ e Java (com o método directAlloc) e manipulá-lo nos dois lados.

someUser
fonte
13

Aqui está um ótimo artigo explicando os benefícios do ByteBuffer. A seguir, são apresentados os principais pontos do artigo:

  • A primeira vantagem de um ByteBuffer, independentemente de ser direta ou indireta, é o acesso aleatório eficiente a dados binários estruturados (por exemplo, E / S de baixo nível, conforme indicado em uma das respostas). Antes do Java 1.4, para ler esses dados, era possível usar um DataInputStream, mas sem acesso aleatório.

A seguir, são apresentados benefícios especificamente para ByteBuffer / MappedByteBuffer direto. Observe que buffers diretos são criados fora do heap:

  1. Não afetado pelos ciclos gc : os buffers diretos não serão movidos durante os ciclos de coleta de lixo, pois residem fora do heap. A tecnologia de cache BigMemory da TerraCota parece confiar fortemente nessa vantagem. Se eles estivessem no heap, isso diminuiria o tempo de pausa do gc.

  2. Aumento de desempenho : no IO do fluxo, as chamadas de leitura envolveriam chamadas do sistema, que exigem uma alternância de contexto entre o modo usuário para kernel e vice-versa, o que seria caro, especialmente se o arquivo estiver sendo acessado constantemente. No entanto, com o mapeamento de memória, essa alternância de contexto é reduzida, pois é mais provável que os dados sejam encontrados na memória (MappedByteBuffer). Se os dados estiverem disponíveis na memória, eles serão acessados ​​diretamente sem chamar o SO, ou seja, sem alternância de contexto.

Observe que MappedByteBuffers são muito úteis, especialmente se os arquivos forem grandes e poucos grupos de blocos forem acessados ​​com mais frequência.

  1. Compartilhamento de página : os arquivos mapeados na memória podem ser compartilhados entre processos à medida que são alocados no espaço de memória virtual do processo e podem ser compartilhados entre processos.
Dheeru Mundluru
fonte