development

Java ByteBuffer에서 문자열로

big-blog 2020. 8. 6. 07:44
반응형

Java ByteBuffer에서 문자열로


이 방법으로 ByteBuffer를 String으로 변환하는 올바른 방법입니까?

String k = "abcd";
ByteBuffer b = ByteBuffer.wrap(k.getBytes());
String v = new String(b.array());

if(k.equals(v))
    System.out.println("it worked");
else
    System.out.println("did not work");

내가 묻는 이유는 이것이 너무 단순 해 보이는 반면 Java 와 같은 다른 접근법 : ByteBuffer와 문자열 변환 및 관련 문제 는 더 복잡해 지기 때문 입니다.


편집 (2018) : @xinyongCheng의 편집 된 형제 답변은 더 간단한 접근법이며 허용되는 답변이어야합니다.

바이트가 플랫폼의 기본 문자 세트에 있다는 것을 알고 있다면 접근 방식이 합리적입니다. 귀하의 예에서는 k.getBytes()플랫폼의 기본 문자 세트에서 바이트를 반환 하기 때문에 이것은 사실 입니다.

더 자주 인코딩을 지정하려고합니다. 그러나 연결 한 질문보다 간단한 방법이 있습니다. String API는 특정 인코딩에서 String과 byte [] 배열 사이를 변환하는 메소드를 제공합니다. 이러한 방법은 CharsetEncoder / CharsetDecoder를 사용하여 "디코딩 [인코딩] 프로세스에 대한 더 많은 제어가 필요한 경우"를 권장 합니다.

특정 인코딩의 문자열에서 바이트를 가져 오려면 형제 getBytes () 메소드를 사용할 수 있습니다.

byte[] bytes = k.getBytes( StandardCharsets.UTF_8 );

특정 인코딩을 가진 바이트를 String에 넣으려면 다른 String 생성자를 사용할 수 있습니다.

String v = new String( bytes, StandardCharsets.UTF_8 );

참고 ByteBuffer.array()옵션 작업입니다. 배열을 사용하여 ByteBuffer를 구성한 경우 해당 배열을 직접 사용할 수 있습니다. 그렇지 않으면, 안전을 원하면 ByteBuffer.get(byte[] dst, int offset, int length)버퍼에서 바이트 배열로 바이트를 가져 오는 데 사용 하십시오.


Andy Thomas가 언급했듯이 ByteBuffera String를 문제없이 디코딩하는 더 간단한 방법이 있습니다 .

String s = StandardCharsets.UTF_8.decode(byteBuffer).toString();

이 시도:

new String(bytebuffer.array(), "ASCII");

NB. 인코딩을 모르면 바이트 배열을 문자열로 올바르게 변환 할 수 없습니다.

이게 도움이 되길 바란다


ByteBuffer.array ()가 항상 작동한다고 가정하는 것은 안전하지 않습니다.

byte[] bytes;
if(buffer.hasArray()) {
    bytes = buffer.array();
} else {
    bytes = new byte[buffer.remaining()];
    buffer.get(bytes);
}
String v = new String(bytes, charset);

일반적으로 buffer.hasArray ()는 사용 사례에 따라 항상 true 또는 false입니다. 실제로 어떤 상황에서도 실제로 작동하지 않으려면 필요하지 않은 지점을 최적화하는 것이 안전합니다. 그러나 나머지 답변은 ByteBuffer.allocateDirect ()를 통해 생성 된 ByteBuffer에서 작동하지 않을 수 있습니다.


The answers referring to simply calling array() are not quite correct: when the buffer has been partially consumed, or is referring to a part of an array (you can ByteBuffer.wrap an array at a given offset, not necessarily from the beginning), we have to account for that in our calculations. This is the general solution that works for buffers in all cases (does not cover encoding):

if (myByteBuffer.hasArray()) {
    return new String(myByteBuffer.array(),
        myByteBuffer.arrayOffset() + myByteBuffer.position(),
        myByteBuffer.remaining());
} else {
    final byte[] b = new byte[myByteBuffer.remaining()];
    myByteBuffer.duplicate().get(b);
    return new String(b);
}

For the concerns related to encoding, see Andy Thomas' answer.


Notice (aside from the encoding issue) that some of the more complicated code linked goes to the trouble of getting the "active" portion of the ByteBuffer in question (for example by using position and limit), rather than simply encoding all of the bytes in the entire backing array (as many of the examples in these answers do).


Convert a String to ByteBuffer, then from ByteBuffer back to String using Java:

import java.nio.charset.Charset;
import java.nio.*;

String babel = "obufscate thdé alphebat and yolo!!";
System.out.println(babel);
//Convert string to ByteBuffer:
ByteBuffer babb = Charset.forName("UTF-8").encode(babel);
try{
    //Convert ByteBuffer to String
    System.out.println(new String(babb.array(), "UTF-8"));
}
catch(Exception e){
    e.printStackTrace();
}

Which prints the printed bare string first, and then the ByteBuffer casted to array():

obufscate thdé alphebat and yolo!!
obufscate thdé alphebat and yolo!!

Also this was helpful for me, reducing the string to primitive bytes can help inspect what's going on:

String text = "こんにちは";
//convert utf8 text to a byte array
byte[] array = text.getBytes("UTF-8");
//convert the byte array back to a string as UTF-8
String s = new String(array, Charset.forName("UTF-8"));
System.out.println(s);
//forcing strings encoded as UTF-8 as an incorrect encoding like
//say ISO-8859-1 causes strange and undefined behavior
String sISO = new String(array, Charset.forName("ISO-8859-1"));
System.out.println(sISO);

Prints your string interpreted as UTF-8, and then again as ISO-8859-1:

こんにちは
ããã«ã¡ã¯

the root of this question is how to decode bytes to string?

this can be done with the JAVA NIO CharSet:

public final CharBuffer decode(ByteBuffer bb)

enter image description here


private String convertFrom(String lines, String from, String to) {
    ByteBuffer bb = ByteBuffer.wrap(lines.getBytes());
    CharBuffer cb = Charset.forName(to).decode(bb);
    return new String(Charset.forName(from).encode(cb).array());
};
public Doit(){
    String concatenatedLines = convertFrom(concatenatedLines, "CP1252", "UTF-8");
};

참고URL : https://stackoverflow.com/questions/17354891/java-bytebuffer-to-string

반응형