Java InputStream vers Byte Array et ByteBuffer

1. Vue d'ensemble

Dans ce rapide tutoriel, nous allons voir comment convertir un InputStream en octet [] et ByteBuffer - d'abord en utilisant Java brut, puis en utilisant Guava et Commons IO.

Cet article fait partie de la série «Java - Back to Basic» ici sur Baeldung.

2. Convertir en tableau d'octets

Voyons comment obtenir un tableau d'octets à partir de flux d'entrée simples . L'aspect important d'un tableau d'octets est qu'il permet un accès indexé (rapide) à chaque valeur de 8 bits (un octet) stockée en mémoire . Par conséquent, vous pouvez manipuler ces octets pour contrôler chaque bit. Nous allons voir comment convertir un flux d'entrée simple en octet [] - d'abord en utilisant Java, puis en utilisant Guava et Apache Commons IO.

2.1. Convertir à l'aide de Java brut

Commençons par une solution Java axée sur le traitement d'un flux de taille fixe:

@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); }

Dans le cas d'un flux tamponné - où nous avons affaire à un flux tamponné et que nous ne connaissons pas la taille exacte des données sous-jacentes, nous devons rendre l'implémentation plus flexible:

@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(); }

À partir de Java 9, nous pouvons réaliser la même chose avec une méthode dédiée sur InputStream :

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

2.2. Convertir à l'aide de la goyave

Regardons maintenant la solution simple basée sur Guava - en utilisant la classe utilitaire ByteStreams pratique:

@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. Convertir à l'aide de Commons IO

Et enfin - une solution simple utilisant 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); }

La méthode IOUtils.toByteArray () met l'entrée en mémoire tampon en interne, il n'est donc pas nécessaire d'utiliser une instance BufferedInputStream lorsqu'une mise en mémoire tampon est nécessaire.

3. Convertir en ByteBuffer

Voyons maintenant comment obtenir un ByteBuffer à partir d'un InputStream. Ceci est utile chaque fois que nous devons effectuer des opérations d'E / S de bas niveau rapides et directes en mémoire .

En utilisant la même approche que les sections ci-dessus, nous allons examiner comment convertir un InputStream en ByteBuffer - d'abord en utilisant Java brut, puis en utilisant Guava et Commons IO.

3.1. Convertir à l'aide de Java brut

Dans le cas d'un flux d'octets - nous connaissons la taille exacte des données sous-jacentes. Utilisons la méthode ByteArrayInputStream # available pour lire le flux d'octets dans un ByteBuffer :

@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. Convertir à l'aide de la goyave

Examinons maintenant une solution simple basée sur Guava - en utilisant la classe utilitaire ByteStreams pratique :

@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); }

Ici, nous utilisons une boucle while avec la méthode hasRemaining pour montrer une manière différente de lire tous les octets dans le ByteBuffer. Sinon, l'assertion échouerait car la position d'index ByteBuffer sera égale à zéro.

3.3. Convertir à l'aide de Commons IO

Et enfin - en utilisant Apache Commons IO et la classe IOUtils :

@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. Conclusion

Cet article a illustré différentes façons de convertir un flux d'entrée brut en un tableau d'octets et un ByteBuffer à l' aide d' E / S Java, Guava et Apache Commons.

L'implémentation de tous ces exemples se trouve dans notre projet GitHub.