IT story

Java에서 문자열을 UTF8 바이트 배열과 변환하는 방법

hot-time 2020. 4. 22. 08:13
반응형

Java에서 문자열을 UTF8 바이트 배열과 변환하는 방법


Java에는 String이 있으며 바이트 배열 (UTF8 또는 다른 인코딩)로 인코딩하려고합니다. 또는 바이트 배열 (일부 알려진 인코딩)이 있고 Java 문자열로 변환하려고합니다. 이러한 전환은 어떻게합니까?


문자열에서 바이트 []로 변환 :

String s = "some text here";
byte[] b = s.getBytes(StandardCharsets.UTF_8);

byte []에서 String으로 변환 :

byte[] b = {(byte) 99, (byte)97, (byte)116};
String s = new String(b, StandardCharsets.US_ASCII);

물론 올바른 인코딩 이름을 사용해야합니다. 내 예제는 가장 일반적인 두 가지 인코딩 인 US-ASCII 및 UTF-8을 사용했습니다.


다음은 모든 전환에 대해 Charset 조회를 수행하지 않는 솔루션입니다.

import java.nio.charset.Charset;

private final Charset UTF8_CHARSET = Charset.forName("UTF-8");

String decodeUTF8(byte[] bytes) {
    return new String(bytes, UTF8_CHARSET);
}

byte[] encodeUTF8(String string) {
    return string.getBytes(UTF8_CHARSET);
}

String original = "hello world";
byte[] utf8Bytes = original.getBytes("UTF-8");

String (byte [], String) 생성자 및 getBytes (String) 메소드 를 통해 직접 변환 할 수 있습니다 . Java는 Charset 클래스 를 통해 사용 가능한 문자 세트를 제공합니다 . JDK 문서 에는 지원되는 인코딩이 나열되어 있습니다.

시간의 90 %, 이러한 변환은 스트림에서 수행되므로 Reader / Writer 클래스를 사용합니다 . 임의의 바이트 스트림에서 String 메소드를 사용하여 점진적으로 디코딩하지는 않습니다. 멀티 바이트 문자와 관련된 버그가 발생할 수 있습니다.


내 tomcat7 구현은 ISO-8859-1과 같은 문자열을 허용합니다. HTTP 요청의 내용 유형에도 불구하고. 'é'와 같은 문자를 올바르게 해석하려고 할 때 다음 해결책이 효과적이었습니다.

byte[] b1 = szP1.getBytes("ISO-8859-1");
System.out.println(b1.toString());

String szUT8 = new String(b1, "UTF-8");
System.out.println(szUT8);

문자열을 US-ASCII로 해석하려고 할 때 바이트 정보가 올바르게 해석되지 않았습니다.

b1 = szP1.getBytes("US-ASCII");
System.out.println(b1.toString());

대안 으로 Apache Commons의 StringUtils 를 사용할 수 있습니다.

 byte[] bytes = {(byte) 1};
 String convertedString = StringUtils.newStringUtf8(bytes);

또는

 String myString = "example";
 byte[] convertedBytes = StringUtils.getBytesUtf8(myString);

비표준 문자 집합 이있는 경우 getBytesUnchecked () 또는 newString ()을 적절하게 사용할 수 있습니다 .


일련의 바이트를 일반 문자열 메시지로 디코딩하기 위해 마침내이 코드로 UTF-8 인코딩으로 작업했습니다.

/* Convert a list of UTF-8 numbers to a normal String
 * Usefull for decoding a jms message that is delivered as a sequence of bytes instead of plain text
 */
public String convertUtf8NumbersToString(String[] numbers){
    int length = numbers.length;
    byte[] data = new byte[length];

    for(int i = 0; i< length; i++){
        data[i] = Byte.parseByte(numbers[i]);
    }
    return new String(data, Charset.forName("UTF-8"));
}

7 비트 ASCII 또는 ISO-8859-1 (놀랍게도 일반적인 형식)을 사용하는 경우 새로운 java.lang.String 을 전혀 만들 필요가 없습니다 . 단순히 바이트를 char로 캐스팅하는 것이 훨씬 더 성능이 좋습니다.

전체 작업 예 :

for (byte b : new byte[] { 43, 45, (byte) 215, (byte) 247 }) {
    char c = (char) b;
    System.out.print(c);
}

당신이 경우 되지 사용하여 확장-문자를 Ä, AE, A, C, I, Ê 같이 하고 있는 유일한 전송 값은, 처음 128 개 유니 코드 문자의 것을 확신 할 수 있습니다 다음이 코드 것 또한 UTF-8 및 확장 ASCII에 대한 작업 (cp-1252와 같은).


//query is your json   

 DefaultHttpClient httpClient = new DefaultHttpClient();
 HttpPost postRequest = new HttpPost("http://my.site/test/v1/product/search?qy=");

 StringEntity input = new StringEntity(query, "UTF-8");
 input.setContentType("application/json");
 postRequest.setEntity(input);   
 HttpResponse response=response = httpClient.execute(postRequest);

댓글을 달 수 없지만 새 스레드를 시작하고 싶지 않습니다. 그러나 이것은 작동하지 않습니다. 간단한 왕복 여행 :

byte[] b = new byte[]{ 0, 0, 0, -127 };  // 0x00000081
String s = new String(b,StandardCharsets.UTF_8); // UTF8 = 0x0000, 0x0000,  0x0000, 0xfffd
b = s.getBytes(StandardCharsets.UTF_8); // [0, 0, 0, -17, -65, -67] 0x000000efbfbd != 0x00000081

인코딩 전후에 b [] 같은 배열이 필요합니다 (이 참조자는 첫 번째 답변을 참조합니다).


Charset UTF8_CHARSET = Charset.forName("UTF-8");
String strISO = "{\"name\":\"א\"}";
System.out.println(strISO);
byte[] b = strISO.getBytes();
for (byte c: b) {
    System.out.print("[" + c + "]");
}
String str = new String(b, UTF8_CHARSET);
System.out.println(str);

Reader reader = new BufferedReader(
    new InputStreamReader(
        new ByteArrayInputStream(
            string.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));

매우 늦었지만 방금이 문제가 발생했으며 이것이 내 수정입니다.

private static String removeNonUtf8CompliantCharacters( final String inString ) {
    if (null == inString ) return null;
    byte[] byteArr = inString.getBytes();
    for ( int i=0; i < byteArr.length; i++ ) {
        byte ch= byteArr[i]; 
        // remove any characters outside the valid UTF-8 range as well as all control characters
        // except tabs and new lines
        if ( !( (ch > 31 && ch < 253 ) || ch == '\t' || ch == '\n' || ch == '\r') ) {
            byteArr[i]=' ';
        }
    }
    return new String( byteArr );
}

참고 : https://stackoverflow.com/questions/88838/how-to-convert-strings-to-and-from-utf8-byte-arrays-in-java

반응형