Java InputStream zu Byte Array und ByteBuffer

1. Übersicht

In diesem kurzen Tutorial sehen wir uns an, wie ein InputStream in ein Byte [] und einen ByteBuffer konvertiert wird - zuerst mit einfachem Java, dann mit Guava und Commons IO.

Dieser Artikel ist Teil der Reihe „Java - Back to Basic“ hier auf Baeldung.

2. In Byte-Array konvertieren

Schauen wir uns an, wie Sie ein Byte-Array aus einfachen Eingabestreams erhalten . Der wichtige Aspekt eines Byte-Arrays besteht darin, dass es einen indizierten (schnellen) Zugriff auf jeden im Speicher gespeicherten 8-Bit-Wert (ein Byte) ermöglicht . Daher können Sie diese Bytes manipulieren, um jedes Bit zu steuern. Wir werden uns ansehen, wie ein einfacher Eingabestream in ein Byte [] konvertiert wird - zuerst mit einfachem Java, dann mit Guava und Apache Commons IO.

2.1. Konvertieren mit einfachem Java

Beginnen wir mit einer Java-Lösung, die sich auf den Umgang mit einem Stream mit fester Größe konzentriert:

@Test public void givenUsingPlainJava_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException { InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 }); byte[] targetArray = new byte[initialStream.available()]; initialStream.read(targetArray); }

Im Fall eines gepufferten Streams - wenn es sich um einen gepufferten Stream handelt und die genaue Größe der zugrunde liegenden Daten nicht bekannt ist, müssen wir die Implementierung flexibler gestalten:

@Test public void givenUsingPlainJavaOnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException { InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 }); // not really unknown ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[1024]; while ((nRead = is.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } buffer.flush(); byte[] byteArray = buffer.toByteArray(); }

Ab Java 9 können wir dasselbe mit einer dedizierten Methode in InputStream erreichen :

@Test public void givenUsingPlainJava9_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException { InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 }); byte[] data = is.readAllBytes(); }

2.2. Konvertieren mit Guave

Schauen wir uns nun die einfache Guava-basierte Lösung an - unter Verwendung der praktischen ByteStreams-Dienstprogrammklasse:

@Test public void givenUsingGuava_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException { InputStream initialStream = ByteSource.wrap(new byte[] { 0, 1, 2 }).openStream(); byte[] targetArray = ByteStreams.toByteArray(initialStream); }

2.3. Konvertieren mit Commons IO

Und schließlich - eine einfache Lösung mit Apache Commons IO:

@Test public void givenUsingCommonsIO_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException { ByteArrayInputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 }); byte[] targetArray = IOUtils.toByteArray(initialStream); }

Die Methode IOUtils.toByteArray () puffert die Eingabe intern, sodass keine BufferedInputStream- Instanz verwendet werden muss, wenn eine Pufferung erforderlich ist.

3. In ByteBuffer konvertieren

Schauen wir uns nun an, wie Sie einen ByteBuffer aus einem InputStream erhalten. Dies ist immer dann nützlich, wenn schnelle und direkte E / A-Operationen auf niedriger Ebene im Speicher ausgeführt werden müssen .

Mit dem gleichen Ansatz wie in den obigen Abschnitten werden wir uns ansehen, wie ein InputStream in einen ByteBuffer konvertiert wird - zuerst mit einfachem Java, dann mit Guava und Commons IO.

3.1. Konvertieren mit einfachem Java

Im Fall eines Bytestreams kennen wir die genaue Größe der zugrunde liegenden Daten. Verwenden wir die verfügbare Methode ByteArrayInputStream # , um den Byte-Stream in einen ByteBuffer einzulesen :

@Test public void givenUsingCoreClasses_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch() throws IOException { byte[] input = new byte[] { 0, 1, 2 }; InputStream initialStream = new ByteArrayInputStream(input); ByteBuffer byteBuffer = ByteBuffer.allocate(3); while (initialStream.available() > 0) { byteBuffer.put((byte) initialStream.read()); } assertEquals(byteBuffer.position(), input.length); }

3.2. Konvertieren mit Guave

Schauen wir uns nun eine einfache Guava-basierte Lösung an - unter Verwendung der praktischen ByteStreams- Dienstprogrammklasse:

@Test public void givenUsingGuava__whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch() throws IOException { InputStream initialStream = ByteSource .wrap(new byte[] { 0, 1, 2 }) .openStream(); byte[] targetArray = ByteStreams.toByteArray(initialStream); ByteBuffer bufferByte = ByteBuffer.wrap(targetArray); while (bufferByte.hasRemaining()) { bufferByte.get(); } assertEquals(bufferByte.position(), targetArray.length); }

Hier verwenden wir eine while-Schleife mit der Methode hasRemaining , um eine andere Methode zum Einlesen aller Bytes in den ByteBuffer zu zeigen. Andernfalls würde die Zusicherung fehlschlagen, da die ByteBuffer-Indexposition Null ist.

3.3. Konvertieren mit Commons IO

Und schließlich - mit Apache Commons IO und der IOUtils- Klasse:

@Test public void givenUsingCommonsIo_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch() throws IOException { byte[] input = new byte[] { 0, 1, 2 }; InputStream initialStream = new ByteArrayInputStream(input); ByteBuffer byteBuffer = ByteBuffer.allocate(3); ReadableByteChannel channel = newChannel(initialStream); IOUtils.readFully(channel, byteBuffer); assertEquals(byteBuffer.position(), input.length); }

4. Fazit

In diesem Artikel wurden verschiedene Möglichkeiten zum Konvertieren eines unformatierten Eingabestreams in ein Byte-Array und einen ByteBuffer unter Verwendung von einfachem Java, Guava und Apache Commons IO veranschaulicht .

Die Implementierung all dieser Beispiele finden Sie in unserem GitHub-Projekt.