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.