แปลง String เป็น Byte Array และ Reverse ใน Java

1. บทนำ

เราจำเป็นต้องแปลงระหว่างสตริงและไบต์อาร์เรย์ใน Java บ่อยครั้ง ในบทช่วยสอนนี้เราจะตรวจสอบการดำเนินการเหล่านี้โดยละเอียด

ขั้นแรกเราจะดูวิธีต่างๆในการแปลงStringเป็นไบต์อาร์เรย์ จากนั้นเราจะดูการดำเนินการที่คล้ายกันในทางกลับกัน

2. การแปลงStringเป็นByte Array

Stringถูกเก็บไว้เป็นอาร์เรย์ของตัวอักษร Unicode ในชวา ในการแปลงเป็นอาร์เรย์ไบต์เราจะแปลลำดับของอักขระเป็นลำดับไบต์ สำหรับการแปลนี้เราจะใช้ตัวอย่างของรหัสตัวอักษร ระดับนี้ระบุการแมประหว่างลำดับที่ถ่านและลำดับของไบต์ s

เราเรียกกระบวนการข้างต้นเป็นเข้ารหัส

เราสามารถเข้ารหัสStringให้เป็นไบต์อาร์เรย์ใน Java ได้หลายวิธี ลองดูรายละเอียดแต่ละข้อพร้อมตัวอย่าง

2.1. ใช้String.getBytes ()

Stringระดับให้สามมากเกินไปgetBytesวิธีการในการเข้ารหัสStringเข้าไบต์อาร์เรย์ :

  • getBytes () - เข้ารหัสโดยใช้ชุดอักขระเริ่มต้นของแพลตฟอร์ม
  • getBytes (String charsetName) - เข้ารหัสโดยใช้ charset ที่มีชื่อ
  • getBytes (Charset charset) - เข้ารหัสโดยใช้ชุดอักขระที่ให้มา

ประการแรกเรามาเข้ารหัสสตริงโดยใช้ชุดอักขระเริ่มต้นของแพลตฟอร์ม:

String inputString = "Hello World!"; byte[] byteArrray = inputString.getBytes();

วิธีการข้างต้นขึ้นอยู่กับแพลตฟอร์มเนื่องจากใช้ชุดอักขระเริ่มต้นของแพลตฟอร์ม เราจะได้รับ charset นี้โดยการเรียกCharset.defaultCharset ()

ประการที่สองเรามาเข้ารหัสสตริงโดยใช้ชุดอักขระที่มีชื่อ:

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

วิธีนี้พ่นUnsupportedEncodingExceptionหากไม่สนับสนุนชุดอักขระที่มีชื่อ

ลักษณะการทำงานของสองเวอร์ชันข้างต้นไม่ได้กำหนดไว้หากอินพุตมีอักขระที่ชุดอักขระไม่รองรับ ในทางตรงกันข้ามเวอร์ชันที่สามใช้อาร์เรย์ไบต์ทดแทนเริ่มต้นของชุดอักขระเพื่อเข้ารหัสอินพุตที่ไม่รองรับ

ต่อไปขอเรียกรุ่นที่สามของเมธอด getBytes ()และส่งผ่านอินสแตนซ์ของCharset:

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

ที่นี่เราจะใช้วิธีการโรงงานCharset.forNameที่จะได้รับตัวอย่างของที่รหัสตัวอักษร วิธีนี้แสดงข้อยกเว้นรันไทม์หากชื่อของชุดอักขระที่ร้องขอไม่ถูกต้อง นอกจากนี้ยังแสดงข้อยกเว้นรันไทม์หากชุดอักขระได้รับการสนับสนุนใน JVM ปัจจุบัน

อย่างไรก็ตามชุดอักขระบางตัวได้รับการรับรองว่าสามารถใช้ได้ในทุกแพลตฟอร์ม Java StandardCharsetsกำหนดระดับค่าคงที่สำหรับชุดอักขระเหล่านี้

สุดท้ายมาเข้ารหัสโดยใช้หนึ่งในชุดอักขระมาตรฐาน:

@Test public void whenGetBytesWithStandardCharset_thenOK() { String inputString = "Hello World!"; Charset charset = StandardCharsets.UTF_16; byte[] byteArrray = inputString.getBytes(charset); assertArrayEquals( new byte[] { -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 }, byteArrray); }

ดังนั้นเราจึงทำการตรวจสอบgetBytesเวอร์ชันต่างๆ ต่อไปเรามาดูวิธีการที่Charset ให้ไว้

2.2. ใช้Charset.encode ()

รหัสตัวอักษรระดับให้เข้ารหัส ()เป็นวิธีที่สะดวกที่ encodes อักขระ Unicode เข้าไบต์ วิธีนี้จะแทนที่อินพุตที่ไม่ถูกต้องและอักขระที่ไม่สามารถใช้งานได้โดยใช้อาร์เรย์ไบต์การแทนที่เริ่มต้นของ charset

มาใช้วิธีการเข้ารหัสเพื่อแปลงStringเป็นไบต์อาร์เรย์:

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

ดังที่เราเห็นด้านบนอักขระที่ไม่รองรับได้ถูกแทนที่ด้วยไบต์การแทนที่เริ่มต้นของชุดอักขระ 63

วิธีการที่ใช้จนถึงตอนนี้ใช้คลาสCharsetEncoderภายในเพื่อทำการเข้ารหัส ลองตรวจสอบชั้นเรียนนี้ในหัวข้อถัดไป

2.3. CharsetEncoder

CharsetEncoderแปลงอักขระ Unicode เป็นลำดับของไบต์สำหรับ charset นอกจากนี้ยังให้การควบคุมขั้นตอนการเข้ารหัสอย่างละเอียด

มาใช้คลาสนี้เพื่อแปลงสตริงเป็นไบต์อาร์เรย์:

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

ที่นี่เรากำลังสร้างอินสแตนซ์ของCharsetEncoderโดยเรียกเมธอดnewEncoderบนวัตถุCharset

จากนั้นเราจะระบุการดำเนินการสำหรับเงื่อนไขข้อผิดพลาดโดยการเรียกonMalformedInput ()และonUnmappableCharacter () วิธีการ เราสามารถระบุการกระทำต่อไปนี้:

  • ไม่สนใจ - ปล่อยข้อมูลที่ผิดพลาด
  • REPLACE - แทนที่อินพุตที่ผิดพลาด
  • REPORT - รายงานข้อผิดพลาดโดยส่งคืนวัตถุCoderResultหรือโยนCharacterCodingException

นอกจากนี้เรากำลังใช้เมธอด replaceWith ()เพื่อระบุอาร์เรย์ไบต์ทดแทน

ดังนั้นเราจึงทำการทบทวนวิธีการต่างๆในการแปลงสตริงเป็นอาร์เรย์ไบต์ ต่อไปมาดูการดำเนินการย้อนกลับ

3. การแปลง Byte Array เป็น String

เราหมายถึงกระบวนการแปลงเป็นไบต์อาร์เรย์ไปStringเป็นถอดรหัส คล้ายกับการเข้ารหัสขั้นตอนนี้ต้องใช้รหัสตัวอักษร

อย่างไรก็ตามเราไม่สามารถใช้ชุดอักขระใด ๆ ในการถอดรหัสอาร์เรย์ไบต์ได้ เราควรใช้ charset ที่ถูกใช้ในการเข้ารหัสStringเข้าสู่ไบต์อาร์เรย์

เราสามารถแปลงไบต์อาร์เรย์เป็น String ได้หลายวิธี ลองตรวจสอบรายละเอียดแต่ละข้อ

3.1. การใช้String Constructor

The String class has few constructors which take a byte array as input. They are all similar to the getBytes method but work in reverse.

First, let's convert a byte array to String using the platform's default charset:

@Test public void whenStringConstructorWithDefaultCharset_thenOK() { byte[] byteArrray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 }; String string = new String(byteArrray); assertNotNull(string); }

Note that we don't assert anything here about the contents of the decoded string. This is because it may decode to something different, depending on the platform's default charset.

For this reason, we should generally avoid this method.

Secondly, let's use a named charset for decoding:

@Test public void whenStringConstructorWithNamedCharset_thenOK() throws UnsupportedEncodingException { String charsetName = "IBM01140"; byte[] byteArrray = { -56, -123, -109, -109, -106, 64, -26, -106, -103, -109, -124, 90 }; String string = new String(byteArrray, charsetName); assertEquals("Hello World!", string); }

This method throws an exception if the named charset is not available on the JVM.

Thirdly, let's use a Charset object to do decoding:

@Test public void whenStringConstructorWithCharSet_thenOK() { Charset charset = Charset.forName("UTF-8"); byte[] byteArrray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 }; String string = new String(byteArrray, charset); assertEquals("Hello World!", string); }

Finally, let's use a standard Charset for the same:

@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 }; String string = new String(byteArrray, charset); assertEquals("Hello World!", string); }

So far, we have converted a byte array into a String using the constructor. Let's now look into the other approaches.

3.2. Using Charset.decode()

The Charset class provides the decode() method that converts a ByteBuffer to String:

@Test public void whenDecodeWithCharset_thenOK() { byte[] byteArrray = { 72, 101, 108, 108, 111, 32, -10, 111, 114, 108, -63, 33 }; Charset charset = StandardCharsets.US_ASCII; String string = charset.decode(ByteBuffer.wrap(byteArrray)) .toString(); assertEquals("Hello �orl�!", string); }

Here, the invalid input is replaced with the default replacement character for the charset.

3.3. CharsetDecoder

แนวทางก่อนหน้านี้ทั้งหมดสำหรับการถอดรหัสภายในใช้คลาสCharsetDecoder เราสามารถใช้คลาสนี้โดยตรงเพื่อควบคุมกระบวนการถอดรหัสอย่างละเอียด :

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

ที่นี่เรากำลังแทนที่อินพุตที่ไม่ถูกต้องและอักขระที่ไม่รองรับด้วย“?”

หากเราต้องการทราบข้อมูลในกรณีที่อินพุตไม่ถูกต้องเราสามารถเปลี่ยนตัวถอดรหัสได้ดังนี้:

decoder.onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT)

4. สรุป

ในบทความนี้เราได้ตรวจสอบหลายวิธีในการแปลงStringเป็นอาร์เรย์ไบต์และย้อนกลับ เราควรเลือกวิธีการที่เหมาะสมโดยพิจารณาจากข้อมูลอินพุตตลอดจนระดับการควบคุมที่จำเป็นสำหรับอินพุตที่ไม่ถูกต้อง

ตามปกติซอร์สโค้ดแบบเต็มสามารถพบได้บน GitHub