Java InputStream u bajtni niz i ByteBuffer

1. Pregled

U ovom brzom vodiču pogledat ćemo kako pretvoriti InputStream do a bajt[] i ByteBuffer - prvo koristeći običnu Javu, a zatim Guavu i Commons IO.

Ovaj je članak dio serije "Java - Povratak na osnovno" ovdje na Baeldungu.

2. Pretvori u bajtni niz

Pogledajmo dobivanje bajt polja iz jednostavnih ulaznih tokova. Važan aspekt bajt polja je taj omogućuje indeksirani (brzi) pristup svakoj 8-bitnoj (bajtnoj) vrijednosti pohranjenoj u memoriji. Dakle, možete upravljati tim bajtovima kako biste kontrolirali svaki bit. Pogledat ćemo kako pretvoriti jednostavni ulazni tok u bajt[] - prvo koristeći običnu Javu, a zatim Guavu i Apache Commons IO.

2.1. Pretvori pomoću obične Jave

Počnimo s Java rješenjem usmjerenim na bavljenje protokom fiksne veličine:

@Test public void givenUsingPlainJava_whenConvertingAnInputStreamToAByteArray_thenCorrect () baca IOException {InputStream InitialStream = new ByteArrayInputStream (novi bajt [] {0, 1, 2}); bajt [] targetArray = novi bajt [InitialStream.available ()]; InitialStream.read (targetArray); }

U slučaju me uspremnika - gdje imamo posla sa međuspremnikom i ne znamo točnu veličinu osnovnih podataka, implementaciju moramo učiniti fleksibilnijom:

@Test public void givenUsingPlainJavaOnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect () baca IOException {InputStream is = new ByteArrayInputStream (novi bajt [] {0, 1, 2}); // zapravo nije nepoznat ByteArrayOutputStream buffer = new ByteArrayOutputStream (); int nRead; bajt [] podaci = novi bajt [1024]; while ((nRead = is.read (data, 0, data.length))! = -1) {buffer.write (data, 0, nRead); } buffer.flush (); byte [] byteArray = buffer.toByteArray (); }

Počevši od Jave 9, to možemo postići namjenskom metodom na InputStream:

@Test public void givenUsingPlainJava9_whenConvertingAnInputStreamToAByteArray_thenCorrect () baca IOException {InputStream is = new ByteArrayInputStream (novi bajt [] {0, 1, 2}); bajt [] podaci = is.readAllBytes (); }

2.2. Pretvorite pomoću Guave

Pogledajmo sada jednostavno rješenje temeljeno na Guavi - koristeći prikladnu uslužnu klasu ByteStreams:

@Test javna praznina givenUsingGuava_whenConvertingAnInputStreamToAByteArray_thenCorrect () baca IOException {InputStream InitialStream = ByteSource.wrap (novi bajt [] {0, 1, 2}). OpenStream (); bajt [] targetArray = ByteStreams.toByteArray (InitialStream); }

2.3. Pretvori pomoću Commons IO

I na kraju, izravno rješenje pomoću Apache Commons IO:

@Test public void givenUsingCommonsIO_whenConvertingAnInputStreamToAByteArray_thenCorrect () baca IOException {ByteArrayInputStream InitialStream = new ByteArrayInputStream (novi bajt [] {0, 1, 2}); bajt [] targetArray = IOUtils.toByteArray (InitialStream); }

Metoda IOUtils.toByteArray () interno puferira ulaz, tako da postoji nema potrebe koristiti a BufferedInputStream primjer kada je potrebno puferiranje.

3. Pretvori u ByteBuffer

Pogledajmo sada dobivanje a ByteBuffer iz an InputStream. Ovo je korisno kad god trebamo raditi brze i izravne I / O operacije u memoriji.

Koristeći isti pristup kao i gornji odjeljci, pogledat ćemo kako pretvoriti InputStream do a ByteBuffer - prvo koristeći običnu Javu, a zatim Guavu i Commons IO.

3.1. Pretvori pomoću obične Jave

U slučaju struje bajtova - znamo točnu veličinu osnovnih podataka. Iskoristimo ByteArrayInputStream # dostupan metoda za čitanje toka bajtova u ByteBuffer:

@Test javna praznina givenUsingCoreClasses_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () baca IOException {byte [] input = new byte [] {0, 1, 2}; InputStream InitialStream = novi ByteArrayInputStream (ulaz); ByteBuffer byteBuffer = ByteBuffer.allocate (3); while (InitialStream.available ()> 0) {byteBuffer.put ((byte) InitialStream.read ()); } assertEquals (byteBuffer.position (), input.length); }

3.2. Pretvorite pomoću Guave

Pogledajmo sada jednostavno rješenje temeljeno na Guavi - koristeći povoljno ByteStreams klasa korisnosti:

@Test javna praznina givenUsingGuava__whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () baca IOException {InputStream InitialStream = ByteSource .wrap (novi bajt [] {0, 1, 2}) .openStream (); bajt [] targetArray = ByteStreams.toByteArray (InitialStream); ByteBuffer bufferByte = ByteBuffer.wrap (targetArray); while (bufferByte.hasRemaining ()) {bufferByte.get (); } assertEquals (bufferByte.position (), targetArray.length); }

Ovdje koristimo while petlju s metodom imaOstalo pokazati drugačiji način čitanja svih bajtova u ByteBuffer. Inače, tvrdnja neće uspjeti jer ByteBuffer položaj indeksa bit će nula.

3.3. Pretvori pomoću Commons IO

I na kraju - pomoću Apache Commons IO i IOUtils razred:

@Test javna praznina givenUsingCommonsIo_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch () baca IOException {byte [] input = new byte [] {0, 1, 2}; InputStream InitialStream = novi ByteArrayInputStream (ulaz); ByteBuffer byteBuffer = ByteBuffer.allocate (3); ReadableByteChannel channel = newChannel (InitialStream); IOUtils.readFully (channel, byteBuffer); assertEquals (byteBuffer.position (), input.length); }

4. Zaključak

Ovaj je članak ilustrirao razne načine pretvaranja sirovog ulaznog toka u bajtni niz i ByteBuffer koristeći obični Java, Guava i Apache Commons IO.

Implementacija svih ovih primjera može se naći u našem GitHub projektu.