Java InputStream naar Byte Array en ByteBuffer

1. Overzicht

In deze korte tutorial gaan we kijken hoe je een InputStream naar een byte[] en ByteBuffer - eerst met gewoon Java, daarna met Guava en Commons IO.

Dit artikel maakt deel uit van de serie "Java - Back to Basic" hier op Baeldung.

2. Converteren naar Byte Array

Laten we eens kijken naar het verkrijgen van een byte-array uit eenvoudige invoerstromen. Het belangrijkste aspect van een byte-array is dat het maakt een geïndexeerde (snelle) toegang mogelijk tot elke 8-bits (een byte) waarde die in het geheugen is opgeslagen. Daarom kunt u deze bytes manipuleren om elke bit te besturen. We gaan kijken hoe je een eenvoudige input-stream naar een byte[] - eerst gewoon Java gebruiken, daarna Guava en Apache Commons IO.

2.1. Converteren met gewone Java

Laten we beginnen met een Java-oplossing die is gericht op het omgaan met een stream met een vaste grootte:

@Test openbare ongeldige gegevenUsingPlainJava_whenConvertingAnInputStreamToAByteArray_thenCorrect () gooit IOException {InputStream initialStream = nieuwe ByteArrayInputStream (nieuwe byte [] {0, 1, 2}); byte [] targetArray = nieuwe byte [initialStream.available ()]; initialStream.read (targetArray); }

In het geval van een gebufferde stream - waar we te maken hebben met een gebufferde stream en de exacte grootte van de onderliggende gegevens niet weten, moeten we de implementatie flexibeler maken:

@Test openbare ongeldige gegevenUsingPlainJavaOnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect () gooit IOException {InputStream is = nieuwe ByteArrayInputStream (nieuwe byte [] {0, 1, 2}); // niet echt onbekend ByteArrayOutputStream buffer = nieuwe ByteArrayOutputStream (); int nRead; byte [] data = nieuwe byte [1024]; while ((nRead = is.read (data, 0, data.length))! = -1) {buffer.write (data, 0, nRead); } buffer.flush (); byte [] byteArray = buffer.toByteArray (); }

Beginnend met Java 9, kunnen we hetzelfde bereiken met een speciale methode op InputStream:

@Test openbare leegte gegevenUsingPlainJava9_whenConvertingAnInputStreamToAByteArray_thenCorrect () gooit IOException {InputStream is = nieuwe ByteArrayInputStream (nieuwe byte [] {0, 1, 2}); byte [] data = is.readAllBytes (); }

2.2. Converteren met behulp van Guava

Laten we nu eens kijken naar de eenvoudige op Guava gebaseerde oplossing - met behulp van de handige ByteStreams utility class:

@Test openbare ongeldige gegevenUsingGuava_whenConvertingAnInputStreamToAByteArray_thenCorrect () gooit IOException {InputStream initialStream = ByteSource.wrap (nieuwe byte [] {0, 1, 2}). OpenStream (); byte [] targetArray = ByteStreams.toByteArray (initialStream); }

2.3. Converteren met Commons IO

En tot slot - een eenvoudige oplossing met Apache Commons IO:

@Test openbare leegte gegevenUsingCommonsIO_whenConvertingAnInputStreamToAByteArray_thenCorrect () gooit IOException {ByteArrayInputStream initialStream = nieuwe ByteArrayInputStream (nieuwe byte [] {0, 1, 2}); byte [] targetArray = IOUtils.toByteArray (initialStream); }

De methode IOUtils.toByteArray () buffert de invoer intern, dus die is er het is niet nodig om een BufferedInputStream voorbeeld wanneer buffering nodig is.

3. Converteren naar ByteBuffer

Laten we nu eens kijken naar het verkrijgen van een ByteBuffer van een InputStream. Dit is handig wanneer we snelle en directe I / O-bewerkingen op laag niveau in het geheugen moeten uitvoeren.

Met dezelfde aanpak als de bovenstaande secties, gaan we bekijken hoe u een InputStream naar een ByteBuffer - eerst met gewoon Java, daarna met Guava en Commons IO.

3.1. Converteren met gewone Java

In het geval van een bytestream kennen we de exacte grootte van de onderliggende gegevens. Laten we de ByteArrayInputStream # beschikbaar methode om de bytestream in een ByteBuffer:

@Test openbare ongeldige gegevenUsingCoreClasses_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () gooit IOException {byte [] input = nieuwe byte [] {0, 1, 2}; InputStream initialStream = nieuwe ByteArrayInputStream (input); ByteBuffer byteBuffer = ByteBuffer.allocate (3); while (initialStream.available ()> 0) {byteBuffer.put ((byte) initialStream.read ()); } assertEquals (byteBuffer.position (), input.length); }

3.2. Converteren met behulp van Guava

Laten we nu eens kijken naar een eenvoudige op Guava gebaseerde oplossing - met behulp van het handige ByteStreams hulpprogramma klasse:

@Test openbare ongeldige gegevenUsingGuava__whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () gooit IOException {InputStream initialStream = ByteSource .wrap (nieuwe 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 gebruiken we een while-lus met de methode hasRemaining om een ​​andere manier te tonen om alle bytes in het ByteBuffer. Anders zou de bewering mislukken omdat de ByteBuffer indexpositie zal nul zijn.

3.3. Converteren met Commons IO

En tot slot - met behulp van Apache Commons IO en de IOUtils klasse:

@Test openbare ongeldige gegevenUsingCommonsIo_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () gooit IOException {byte [] input = nieuwe byte [] {0, 1, 2}; InputStream initialStream = nieuwe ByteArrayInputStream (input); ByteBuffer byteBuffer = ByteBuffer.allocate (3); ReadableByteChannel kanaal = newChannel (initialStream); IOUtils.readFully (kanaal, byteBuffer); assertEquals (byteBuffer.position (), input.length); }

4. Conclusie

Dit artikel illustreert verschillende manieren om een ​​onbewerkte invoerstroom naar een byte-array en een ByteBuffer met behulp van gewone Java, Guava en Apache Commons IO.

De implementatie van al deze voorbeelden is te vinden in ons GitHub-project.