Java InputStream zu Byte Array und ByteBuffer
1. Überblick
In diesem kurzen Tutorial sehen wir uns an, wie SieInputStream inbyte[] undByteBuffer konvertieren - zuerst mit einfachem Java, dann mit Guava und Commons IO.
Dieser Artikel ist Teil vonthe “Java – Back to Basic” series hier am Beispiel.
Weitere Lektüre:
Einführung in die Java-Serialisierung
Wir lernen, wie man Objekte in Java serialisiert und deserialisiert.
Java-String-Konvertierungen
Schnelle und praktische Beispiele zur Konvertierung von String-Objekten in verschiedene Datentypen in Java.
2. In Byte-Array konvertieren
Betrachten wir das Erhalten eines Byte-Arrays aus einfachen Eingabestreams. Der wichtige Aspekt eines Byte-Arrays istit enables an indexed (fast) access to each 8-bit (a byte) value stored in memory. Daher können Sie diese Bytes manipulieren, um jedes Bit zu steuern. Wir werden uns ansehen, wie ein einfacher Eingabestream inbyte[] konvertiert wird - zuerst mit einfachem Java, dann mitGuava undApache 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();
}
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 unkomplizierte 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 MethodeIOUtils.toByteArray() puffert die Eingabe intern, sodassno need to use a BufferedInputStream instance vorhanden ist, wenn eine Pufferung erforderlich ist.
3. InByteBuffer umrechnen
Schauen wir uns nun an, wie SieByteBuffer vonInputStream. erhalten. Dies istuseful whenever we need to do fast and direct low-level I/O operations in memory.
Mit dem gleichen Ansatz wie in den obigen Abschnitten werden wir uns ansehen, wie einInputStream in einByteBuffer konvertiert wird - zuerst mit einfachem Java, dann mit Guava und Commons IO.
3.1. Konvertieren mit einfachem Java
Im Fall eines Byte-Streams kennen wir die genaue Größe der zugrunde liegenden Daten. Verwenden Sie die MethodeByteArrayInputStream#available , um den Bytestream inByteBuffer 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 DienstprogrammklasseByteStreams:
@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 MethodehasRemaining , um eine andere Methode zum Einlesen aller Bytes inByteBuffer.zu zeigen. Andernfalls würde die Zusicherung fehlschlagen, da die Indexposition vonByteBufferNull ist.
3.3. Konvertieren mit Commons IO
Und schließlich - mit Apache Commons IO und der KlasseIOUtils:
@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 einByteBuffer mithilfe von einfachem Java, Guava und Apache Commons IO erläutert.
Die Implementierung all dieser Beispiele finden Sie in unserenGitHub project.