Pretvori niz u bajtni niz i obrni u Javi

1. Uvod

Često moramo pretvoriti između Niz i bajt niz u Javi. U ovom uputstvu detaljno ćemo ispitati ove operacije.

Prvo ćemo pogledati razne načine pretvaranja a Niz do a bajt niz. Zatim ćemo slične operacije pogledati obrnuto.

2. Pretvaranje Niz do Bajt Polje

A Niz pohranjen je kao niz Unicode znakova u Javi. Da biste ga pretvorili u bajt niz, prevodimo slijed znakova u slijed bajtova. Za ovaj prijevod, koristimo primjerak Charset. Ova klasa navodi mapiranje između niza od ugljens i slijed od bajts.

Gornji postupak nazivamo: kodiranje.

Možemo kodirati a Niz u a bajt niz u Javi na više načina. Pogledajmo svaku od njih detaljno s primjerima.

2.1. Koristeći String.getBytes ()

The Niz klasa pruža tri preopterećena getBytes metode za kodiranje a Niz u bajt niz:

  • getBytes () - kodira koristeći zadani charset platforme
  • getBytes (String charsetName) - kodira pomoću imenovanog znaka
  • getBytes (charset charset) - kodira pomoću priloženog znaka

Prvo, kodirajmo niz koristeći zadani skup znakova platforme:

String inputString = "Pozdrav svijetu!"; bajt [] byteArrray = inputString.getBytes ();

Gornja metoda ovisi o platformi jer koristi zadani skup znakova platforme. Ovu skup znakova možemo dobiti pozivom Charset.defaultCharset ().

Drugo, kodirajmo niz pomoću imenovanog znaka:

@Test public void whenGetBytesWithNamedCharset_thenOK () baca UnsupportedEncodingException {String inputString = "Hello World!"; Niz charsetName = "IBM01140"; bajt [] byteArrray = inputString.getBytes ("IBM01140"); assertArrayEquals (novi bajt [] {-56, -123, -109, -109, -106, 64, -26, -106, -103, -109, -124, 90}, byteArrray); }

Ova metoda baca UnsupportedEncodingException ako imenovani skup znakova nije podržan.

Ponašanje gornje dvije verzije nije definirano ako ulaz sadrži znakove koje charset ne podržava. Suprotno tome, treća verzija koristi zadani niz zamjenskih bajtova charseta za kodiranje nepodržanih unosa.

Sljedeći, nazovimo treću verziju getBytes () metoda i proslijedi instancu Charset:

@Test public void whenGetBytesWithCharset_thenOK () {String inputString = "Pozdrav ਸੰਸਾਰ!"; Charset charset = Charset.forName ("ASCII"); byte [] byteArrray = inputString.getBytes (charset); assertArrayEquals (novi bajt [] {72, 101, 108, 108, 111, 32, 63, 63, 63, 63, 63, 33}, byteArrray); }

Ovdje koristimo tvorničku metodu Charset.zaName da biste dobili instancu Charset. Ova metoda baca runtime iznimku ako je ime traženog znaka pogrešno. Također izbacuje runtime iznimku ako je charset podržan u trenutnom JVM-u.

Međutim, neki skupovi znakova bit će zajamčeni na svakoj Java platformi. The StandardCharsets class definira konstante za ove znakove.

Konačno, kodirajmo pomoću jednog od standardnih znakova:

@Test public void whenGetBytesWithStandardCharset_thenOK () {String inputString = "Hello World!"; Charset charset = StandardCharsets.UTF_16; byte [] byteArrray = inputString.getBytes (charset); assertArrayEquals (novi bajt [] {-2, -1, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0 , 108, 0, 100, 0, 33}, bajtArrray); }

Dakle, dovršavamo pregled različitih getBytes verzije. Dalje, pogledajmo metodu koju pruža Charset sebe.

2.2. Koristeći Charset.encode ()

The Charset razred pruža kodiraj (), prikladna metoda koja kodira Unicode znakove u bajtove. Ova metoda uvijek zamjenjuje nevaljane unose i znakove koji se ne mogu preslikati koristeći zadani niz bajtova zamjenskog znaka.

Iskoristimo kodirati metoda za pretvorbu a Niz u a bajt niz:

@Test public void whenEncodeWithCharset_thenOK () {String inputString = "Pozdrav ਸੰਸਾਰ!"; Charset charset = StandardCharsets.US_ASCII; byte [] byteArrray = charset.encode (inputString) .array (); assertArrayEquals (novi bajt [] {72, 101, 108, 108, 111, 32, 63, 63, 63, 63, 63, 33}, byteArrray); }

Kao što gore možemo vidjeti, nepodržani znakovi zamijenjeni su zadanom zamjenom znaka bajt 63.

Do sada korišteni pristupi koriste CharsetEncoder klasa interno za izvođenje kodiranja. Ispitajmo ovu nastavu u sljedećem odjeljku.

2.3. CharsetEncoder

CharsetEncoder pretvara Unicode znakove u slijed bajtova za zadani skup znakova. Štoviše, pruža preciznu kontrolu nad postupkom kodiranja.

Upotrijebimo ovu klasu za pretvorbu a Niz u a bajt niz:

@Test public void whenUsingCharsetEncoder_thenOK () baca CharacterCodingException {String inputString = "Hello ਸੰਸਾਰ!"; CharsetEncoder encoder = StandardCharsets.US_ASCII.newEncoder (); encoder.onMalformedInput (CodingErrorAction.IGNORE) .onUnmappableCharacter (CodingErrorAction.REPLACE) .replaceWith (novi bajt [] {0}); byte [] byteArrray = encoder.encode (CharBuffer.wrap (inputString)) .array (); assertArrayEquals (novi bajt [] {72, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 33}, byteArrray); }

Ovdje stvaramo primjerak CharsetEncoder pozivom na newEncoder metoda na a Charset objekt.

Zatim specificiramo radnje za uvjete pogreške pozivanjem datoteke onMalformedInput () i onUnmappableCharacter () metode. Možemo odrediti sljedeće radnje:

  • IGNORE - ispustite pogrešan ulaz
  • ZAMJENA - zamijenite pogrešan ulaz
  • IZVJEŠĆI - prijavite pogrešku vraćanjem a CoderResult predmet ili bacanje a CharacterCodingException

Nadalje, koristimo zamijeniti s() metoda za određivanje zamjene bajt niz.

Dakle, dovršavamo pregled različitih pristupa pretvaranju niza u bajtni niz. Pogledajmo dalje obrnutu operaciju.

3. Pretvaranje bajt polja u niz

Mislimo na postupak pretvaranja a bajt niz do a Niz kao dekodiranje. Slično kodiranju, i ovaj postupak zahtijeva Charset.

Međutim, ne možemo samo koristiti bilo koji skup znakova za dekodiranje bajt polja. Trebali bismo koristiti charset koji je korišten za kodiranje Niz u bajt niz.

Niz bajtova u niz možemo pretvoriti u String. Ispitajmo svaki od njih detaljno.

3.1. Koristiti Niz Konstruktor

The Niz klasa ima nekoliko konstruktora koji uzimaju a bajt niz kao ulaz. Svi su slični getBytes metoda, ali raditi obrnuto.

Prvi, pretvorimo niz bajtova u Niz koristeći zadani skup znakova platforme:

@Test javna praznina kadaStringConstructorWithDefaultCharset_thenOK () {byte [] byteArrray = {72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33}; Niz niza = novi niz (byteArrray); assertNotNull (niz); }

Imajte na umu da ovdje ne tvrdimo ništa o sadržaju dekodiranog niza. To je zato što se može dekodirati na nešto drugačije, ovisno o zadanom skupu znakova na platformi.

Iz tog razloga, općenito bismo trebali izbjegavati ovu metodu.

Drugo, upotrijebimo imenovani skup znakova za dekodiranje:

@Test public void whenStringConstructorWithNamedCharset_thenOK () baca UnsupportedEncodingException {String charsetName = "IBM01140"; byte [] byteArrray = {-56, -123, -109, -109, -106, 64, -26, -106, -103, -109, -124, 90}; Niz niza = novi niz (byteArrray, charsetName); assertEquals ("Pozdrav svijetu!", niz); }

Ova metoda baca iznimku ako imenovani skup znakova nije dostupan na JVM-u.

Treće, poslužimo se a Charset objekt za dekodiranje:

@Test public void whenStringConstructorWithCharSet_thenOK () {Charset charset = Charset.forName ("UTF-8"); bajt [] bajtArrray = {72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33}; Niz niza = novi niz (byteArrray, charset); assertEquals ("Pozdrav svijetu!", niz); }

Konačno, poslužimo se standardom Charset za isto:

@Test public void whenStringConstructorWithStandardCharSet_thenOK () {Charset charset = StandardCharsets.UTF_16; byte [] byteArrray = {-2, -1, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0, 33}; Niz niza = novi niz (byteArrray, charset); assertEquals ("Pozdrav svijetu!", niz); }

Do sada smo pretvorili a bajt niz u Niz pomoću konstruktora. Pogledajmo sada ostale pristupe.

3.2. Koristeći Charset.decode ()

The Charset razred pruža dekodiraj () metoda koja pretvara a ByteBuffer do Niz:

@Test javna void whenDecodeWithCharset_thenOK () {byte [] byteArrray = {72, 101, 108, 108, 111, 32, -10, 111, 114, 108, -63, 33}; Charset charset = StandardCharsets.US_ASCII; Niz niza = charset.decode (ByteBuffer.wrap (byteArrray)) .toString (); assertEquals ("Pozdrav  orl !", niz); }

Ovdje, nevaljani unos zamjenjuje se zadanim zamjenskim znakom za charset.

3.3. CharsetDecoder

Svi prethodni pristupi za interno dekodiranje koriste CharsetDecoder razred. Ovu klasu možemo koristiti izravno za preciznu kontrolu postupka dekodiranja:

@Test public void whenUsingCharsetDecoder_thenOK () baca CharacterCodingException {byte [] byteArrray = {72, 101, 108, 108, 111, 32, -10, 111, 114, 108, -63, 33}; Dekoder CharsetDecoder = StandardCharsets.US_ASCII.newDecoder (); decoder.onMalformedInput (CodingErrorAction.REPLACE) .onUnmappableCharacter (CodingErrorAction.REPLACE) .replaceWith ("?"); Niz niza = decoder.decode (ByteBuffer.wrap (byteArrray)) .toString (); assertEquals ("Halo? orl ?!", niz); }

Ovdje zamjenjujemo nevaljane unose i nepodržane znakove s "?".

Ako želimo biti obaviješteni u slučaju nevaljanih unosa, možemo promijeniti dekoder kao:

dekoder.onMalformedInput (CodingErrorAction.REPORT) .onUnmappableCharacter (CodingErrorAction.REPORT)

4. Zaključak

U ovom smo članku istražili više načina za pretvorbu Niz na niz bajtova i obrnuto. Trebali bismo odabrati odgovarajuću metodu na temelju ulaznih podataka kao i razine kontrole potrebne za nevaljane ulaze.

Kao i obično, puni izvorni kod možete pronaći na GitHubu.