Java InputStream til Byte Array og ByteBuffer

1. Oversigt

I denne hurtige vejledning skal vi se på, hvordan man konverterer en InputStream til en byte [] og ByteBuffer - først ved hjælp af almindelig Java, derefter ved hjælp af Guava og Commons IO.

Denne artikel er en del af "Java - Back to Basic" -serien her på Baeldung.

2. Konverter til Byte Array

Lad os se på at få et byte-array fra enkle inputstrømme. Det vigtige aspekt af et byte-array er det det muliggør en indekseret (hurtig) adgang til hver 8-bit (en byte) værdi, der er gemt i hukommelsen. Derfor kan du manipulere disse bytes til at kontrollere hver bit. Vi skal se på, hvordan man konverterer en simpel inputstrøm til en byte [] - først ved hjælp af almindelig Java, derefter ved hjælp af Guava og Apache Commons IO.

2.1. Konverter ved hjælp af almindelig Java

Lad os starte med en Java-løsning med fokus på at håndtere en strøm i fast størrelse:

@Test offentlig ugyldighed givenUsingPlainJava_whenConvertingAnInputStreamToAByteArray_thenCorrect () kaster IOException {InputStream initialStream = ny ByteArrayInputStream (ny byte [] {0, 1, 2}); byte [] targetArray = ny byte [initialStream.available ()]; initialStream.read (targetArray); }

I tilfælde af en bufret strøm - hvor vi har at gøre med en bufferet strøm og ikke kender den nøjagtige størrelse af de underliggende data, er vi nødt til at gøre implementeringen mere fleksibel:

@Test offentlig ugyldighed givenUsingPlainJavaOnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect () kaster IOException {InputStream er = ny ByteArrayInputStream (ny byte [] {0, 1, 2}); // ikke rigtig ukendt ByteArrayOutputStream-buffer = ny ByteArrayOutputStream (); int nLæs; byte [] data = ny byte [1024]; mens ((nRead = is.read (data, 0, data.length))! = -1) {buffer.write (data, 0, nRead); } buffer.flush (); byte [] byteArray = buffer.toByteArray (); }

Fra og med Java 9 kan vi opnå det samme med en dedikeret metode til InputStream:

@Test offentlig ugyldighed givenUsingPlainJava9_whenConvertingAnInputStreamToAByteArray_thenCorrect () kaster IOException {InputStream er = ny ByteArrayInputStream (ny byte [] {0, 1, 2}); byte [] data = is.readAllBytes (); }

2.2. Konverter ved hjælp af Guava

Lad os nu se på den enkle Guava-baserede løsning - ved hjælp af den praktiske ByteStreams-hjælpeklasse:

@Test offentlig ugyldighed givenUsingGuava_whenConvertingAnInputStreamToAByteArray_thenCorrect () kaster IOException {InputStream initialStream = ByteSource.wrap (ny byte [] {0, 1, 2}). OpenStream (); byte [] targetArray = ByteStreams.toByteArray (initialStream); }

2.3. Konverter ved hjælp af Commons IO

Og endelig - en ligetil løsning ved hjælp af Apache Commons IO:

@Test offentlig ugyldighed givenUsingCommonsIO_whenConvertingAnInputStreamToAByteArray_thenCorrect () kaster IOException {ByteArrayInputStream initialStream = ny ByteArrayInputStream (ny byte [] {0, 1, 2}); byte [] targetArray = IOUtils.toByteArray (initialStream); }

Metoden IOUtils.toByteArray () buffere input internt, så der er ingen grund til at bruge en BufferedInputStream eksempel når der er behov for buffering.

3. Konverter til ByteBuffer

Lad os nu se på at få en ByteBuffer fra en InputStream. Dette er nyttigt, når vi har brug for at udføre hurtige og direkte I / O-operationer på lavt niveau i hukommelsen.

Ved hjælp af samme tilgang som ovenstående afsnit vil vi se på, hvordan man konverterer en InputStream til en ByteBuffer - først ved hjælp af almindelig Java, derefter ved hjælp af Guava og Commons IO.

3.1. Konverter ved hjælp af almindelig Java

I tilfælde af en byte-stream - kender vi den nøjagtige størrelse af de underliggende data. Lad os bruge ByteArrayInputStream # tilgængelig metode til at læse byte-strømmen ind i en ByteBuffer:

@Test offentlig ugyldighed givenUsingCoreClasses_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () kaster IOException {byte [] input = ny byte [] {0, 1, 2}; InputStream initialStream = ny ByteArrayInputStream (input); ByteBuffer byteBuffer = ByteBuffer.allocate (3); mens (initialStream.available ()> 0) {byteBuffer.put ((byte) initialStream.read ()); } assertEquals (byteBuffer.position (), input.length); }

3.2. Konverter ved hjælp af Guava

Lad os nu se på en simpel Guava-baseret løsning - ved hjælp af det praktiske ByteStreams utility klasse:

@Test offentlig ugyldighed givenUsingGuava__whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () smider IOException {InputStream initialStream = ByteSource .wrap (ny byte [] {0, 1, 2}) .openStream (); byte [] targetArray = ByteStreams.toByteArray (initialStream); ByteBuffer bufferByte = ByteBuffer.wrap (targetArray); mens (bufferByte.hasRemaining ()) {bufferByte.get (); } assertEquals (bufferByte.position (), targetArray.length); }

Her bruger vi en while-loop med metoden harResterende for at vise en anden måde at læse alle bytes i ByteBuffer. Ellers ville påstanden mislykkes, fordi ByteBuffer indeksposition vil være nul.

3.3. Konverter ved hjælp af Commons IO

Og endelig - ved hjælp af Apache Commons IO og IOUtils klasse:

@Test offentlig ugyldighed givenUsingCommonsIo_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () kaster IOException {byte [] input = ny byte [] {0, 1, 2}; InputStream initialStream = ny ByteArrayInputStream (input); ByteBuffer byteBuffer = ByteBuffer.allocate (3); ReadableByteChannel channel = newChannel (initialStream); IOUtils.readFully (kanal, byteBuffer); assertEquals (byteBuffer.position (), input.length); }

4. Konklusion

Denne artikel illustrerede forskellige måder at konvertere en rå inputstrøm til et byte-array og en ByteBuffer ved hjælp af almindelig Java, Guava og Apache Commons IO.

Implementeringen af ​​alle disse eksempler kan findes i vores GitHub-projekt.