Was ist die Verwendung von ByteBuffer in Java? [geschlossen]

197

Was sind Beispielanwendungen für a ByteBufferin Java? Bitte listen Sie alle Beispielszenarien auf, in denen dies verwendet wird. Danke dir!

Aklin
quelle
1
Die Komprimierung von Apache Hadoop (z. B. Zlib-Codec) verwendet ByteBuffer aus jave.nio.
Nikk
Gut zum Senden von Daten an GPUs.
Pixel

Antworten:

137

Dies ist eine gute Beschreibung seiner Verwendungen und Mängel. Sie verwenden es im Wesentlichen immer dann, wenn Sie schnelle Low-Level-E / A ausführen müssen. Wenn Sie ein TCP / IP-Protokoll implementieren oder eine Datenbank (DBMS) schreiben würden, wäre diese Klasse nützlich.

kelloti
quelle
3
Ist es irgendwo nützlich in einer stark frequentierten Website, die mit Java & Cassandra DB entwickelt wurde?
Aklin
1
Nach einer kurzen Suche scheint es, dass Cassandra ByteBuffer verwendet: mail-archive.com/[email protected]/msg14967.html Wenn Sie sich über eine unformatierte Website wundern, gibt es diese möglicherweise, aber normalerweise nur wird indirekt von Websites verwendet - mit Tools wie
Cassandra
1
Kein schlechter Link, danke. möchte dieses hinzufügen, das ich nützlich fand - worldmodscode.wordpress.com/2012/12/14/…
Peter Perháč
Schlechter Link, fürchte ich ...
RoyalBigMack
96

Die ByteBuffer-Klasse ist wichtig, da sie eine Grundlage für die Verwendung von Kanälen in Java bildet. Die ByteBuffer- Klasse definiert sechs Kategorien von Operationen für Bytepuffer , wie in der Java 7-Dokumentation angegeben :

  • Absolute und relative Get- und Put- Methoden, die einzelne Bytes lesen und schreiben;

  • Relative Bulk-Get- Methoden, die zusammenhängende Folgen von Bytes aus diesem Puffer in ein Array übertragen.

  • Relative Bulk-Put- Methoden, die zusammenhängende Folgen von Bytes von einem Byte-Array oder einem anderen Byte-Puffer in diesen Puffer übertragen;

  • Absolute und relative Get- und Put-Methoden, die Werte anderer primitiver Typen lesen und schreiben und sie in und aus Sequenzen von Bytes in einer bestimmten Bytereihenfolge übersetzen;

  • Methoden zum Erstellen von Ansichtspuffern, mit denen ein Bytepuffer als Puffer angesehen werden kann, der Werte eines anderen primitiven Typs enthält; und

  • Methoden zum Komprimieren , Duplizieren und Schneiden eines Bytepuffers.

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
quelle
56
Der Großteil dieses Kommentars wird aus den Java 7-Dokumenten kopiert .
Janus Troelsen
6
Ich glaube, Sie verwenden die falsche Methode für den absoluten Put, es sei denn, Sie nutzen eine nicht offensichtliche Nebenwirkung aus. Der Javadoc scheint anzuzeigen, dass für den absoluten Put ein Indexwert erforderlich ist.
Chuck Wolber
6
Selbst wenn es nur eine Kopie des API-Dokuments ist, ist es sogar schlechter als seine Punktzahl. Einige Leute scheinen zu faul zu sein, um es sich anzusehen.
Chris
1
In einem der Beispiele liegt ein Fehler vor. Beim "absoluten Put" fehlt der erste Parameter, der den Index darstellt (in diesem Fall 0).
bvdb
21

Java IO unter Verwendung von Stream-orientierten APIs wird unter Verwendung eines Puffers als temporäre Speicherung von Daten im Benutzerbereich ausgeführt. Von DMA von der Festplatte gelesene Daten werden zuerst in Puffer im Kernelraum kopiert, die dann in den Puffer im Benutzerraum übertragen werden. Daher gibt es Overhead. Wenn Sie dies vermeiden, können Sie einen erheblichen Leistungsgewinn erzielen.

Wir könnten diesen temporären Puffer im Benutzerbereich überspringen, wenn es eine Möglichkeit gäbe, direkt auf den Puffer im Kernelbereich zuzugreifen. Java NIO bietet eine Möglichkeit, dies zu tun.

ByteBuffergehört zu mehreren von Java NIO bereitgestellten Puffern. Es ist nur ein Container oder ein Vorratsbehälter zum Lesen oder Schreiben von Daten. Das obige Verhalten wird durch Zuweisen eines direkten Puffers mithilfe der allocateDirect()API für den Puffer erreicht.

Die Java-Dokumentation des Bytepuffers enthält nützliche Informationen.

deepujain
quelle
14

In Android können Sie einen gemeinsamen Puffer zwischen C ++ und Java (mit der directAlloc-Methode) erstellen und auf beiden Seiten bearbeiten.

someUser
quelle
13

Hier ist ein großartiger Artikel, der die Vorteile von ByteBuffer erklärt. Im Folgenden sind die wichtigsten Punkte des Artikels aufgeführt:

  • Der erste Vorteil eines ByteBuffers, unabhängig davon, ob er direkt oder indirekt ist, ist ein effizienter Direktzugriff auf strukturierte Binärdaten (z. B. Low-Level-IO, wie in einer der Antworten angegeben). Vor Java 1.4 konnte zum Lesen solcher Daten ein DataInputStream verwendet werden, jedoch ohne wahlfreien Zugriff.

Im Folgenden finden Sie Vorteile speziell für direkten ByteBuffer / MappedByteBuffer. Beachten Sie, dass direkte Puffer außerhalb des Heapspeichers erstellt werden:

  1. Von GC-Zyklen nicht betroffen : Direkte Puffer werden während der Speicherbereinigungszyklen nicht verschoben, da sie sich außerhalb des Heaps befinden. Die BigMemory- Caching-Technologie von TerraCota scheint stark von diesem Vorteil abhängig zu sein . Wenn sie auf einem Haufen wären, würde dies die Pausenzeiten verlangsamen.

  2. Leistungssteigerung : In Stream-E / A würden Leseaufrufe Systemaufrufe beinhalten, die einen Kontextwechsel zwischen Benutzer in den Kernelmodus und umgekehrt erfordern, was insbesondere dann kostspielig wäre, wenn ständig auf Dateien zugegriffen wird. Mit der Speicherzuordnung wird diese Kontextumschaltung jedoch reduziert, da Daten eher im Speicher gefunden werden (MappedByteBuffer). Wenn Daten im Speicher verfügbar sind, wird direkt auf sie zugegriffen, ohne das Betriebssystem aufzurufen, dh ohne Kontextwechsel.

Beachten Sie, dass MappedByteBuffers sehr nützlich sind, insbesondere wenn die Dateien groß sind und nur wenige Gruppen von Blöcken häufiger aufgerufen werden.

  1. Seitenfreigabe : Speicherzugeordnete Dateien können von Prozessen gemeinsam genutzt werden, da sie im virtuellen Speicherbereich des Prozesses zugewiesen und prozessübergreifend freigegeben werden.
Dheeru Mundluru
quelle