문자열을 바이트 배열로 변환하고 Java에서 반전

1. 소개

Java에서 문자열바이트 배열 사이를 자주 변환해야합니다 . 이 자습서에서는 이러한 작업을 자세히 살펴 보겠습니다.

먼저 문자열바이트 배열 로 변환하는 다양한 방법을 살펴 보겠습니다 . 그런 다음 유사한 작업을 반대로 살펴 보겠습니다.

2. 문자열바이트 배열로 변환

문자열 자바에서 유니 코드 문자의 배열로 저장됩니다. 이를 바이트 배열 로 변환하기 위해 문자 시퀀스를 바이트 시퀀스로 변환합니다. 이 번역에서는 Charset 인스턴스를 사용합니다 . 이 클래스의 시퀀스 간의 맵핑 지정 문자 들 및 일련의 바이트 .

위의 과정을 인코딩이라고 합니다.

우리는 여러 방법으로 Java에서 문자열바이트 배열 로 인코딩 할 수 있습니다 . 예제를 통해 각각을 자세히 살펴 보겠습니다.

2.1. 사용 ) (하는 String.getBytes를

문자열 클래스 세 과부하 제공 getBytes의 인코딩하는 방법을 문자열바이트 배열 :

  • getBytes () – 플랫폼의 기본 문자 집합을 사용하여 인코딩
  • getBytes (String charsetName) – 명명 된 charset을 사용하여 인코딩합니다.
  • getBytes (Charset charset) – 제공된 charset을 사용하여 인코딩합니다.

먼저 플랫폼의 기본 문자 집합을 사용하여 문자열을 인코딩 해 보겠습니다.

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

위의 방법은 플랫폼의 기본 문자 집합을 사용하므로 플랫폼에 따라 다릅니다. 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을 throw 합니다.

입력에 문자 집합에서 지원하지 않는 문자가 포함 된 경우 위 두 버전의 동작은 정의되지 않습니다. 대조적으로, 세 번째 버전은 지원되지 않는 입력을 인코딩하기 위해 charset의 기본 대체 바이트 배열을 사용합니다.

다음으로, 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을 의 인스턴스를 얻을 캐릭터 세트를 . 이 메서드는 요청 된 문자 집합의 이름이 유효하지 않은 경우 런타임 예외를 throw합니다. 현재 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를

캐릭터 세트 클래스를 제공 인코딩 () , 바이트로 유니 코드 문자를 인코딩하는 편리한 방법을. 이 메서드는 항상 charset의 기본 대체 바이트 배열을 사용하여 유효하지 않은 입력 및 매핑 할 수없는 문자를 대체합니다.

encode 메소드를 사용하여 문자열바이트 배열 로 변환 해 보겠습니다 .

@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 는 유니 코드 문자를 주어진 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); }

여기에서는 Charset 개체 에 대해 newEncoder 메서드를 호출하여 CharsetEncoder 의 인스턴스를 만듭니다.

그런 다음 onMalformedInput ()onUnmappableCharacter () 메서드 를 호출하여 오류 조건에 대한 작업을 지정 합니다 . 다음 작업을 지정할 수 있습니다.

  • IGNORE – 잘못된 입력 삭제
  • REPLACE – 잘못된 입력 교체
  • REPORT – CoderResult 객체 를 반환 하거나 CharacterCodingException을 발생시켜 오류를보고합니다.

또한 대체 바이트 배열 을 지정하기 위해 replaceWith () 메서드를 사용하고 있습니다.

따라서 우리는 문자열을 바이트 배열로 변환하는 다양한 접근 방식에 대한 검토를 완료합니다. 다음으로 역 동작을 살펴 보겠습니다.

3. 바이트 배열을 문자열로 변환

바이트 배열을 문자열 로 변환하는 과정을 디코딩이라고 합니다. 인코딩과 마찬가지로이 프로세스에는 Charset 이 필요합니다 .

그러나 바이트 배열을 디코딩하는 데 문자 집합을 사용할 수는 없습니다. 문자열바이트 배열 인코딩하는 데 사용 된 문자셋을 사용해야합니다 .

여러 방법으로 바이트 배열을 문자열로 변환 할 수 있습니다. 각각에 대해 자세히 살펴 보겠습니다.

3.1. 은 Using 문자열 생성자

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. 결론

이 기사에서는 문자열 을 바이트 배열 로 변환 하고 반대로 변환하는 여러 방법을 조사했습니다 . 입력 데이터와 유효하지 않은 입력에 필요한 제어 수준에 따라 적절한 방법을 선택해야합니다.

평소처럼 전체 소스 코드는 GitHub에서 찾을 수 있습니다.