Java 바이트 배열에서 문자열로 바이트 배열로


180

byte []에서 문자열로, byte []에서 byte [] 로의 문자열 표현을 이해하려고 노력하고 있습니다 ... 나는 byte []를 보낼 문자열로 변환 한 다음 웹 서비스 (파이썬으로 작성)를 기대합니다 클라이언트로 데이터를 바로 에코합니다.

Java 애플리케이션에서 데이터를 보낼 때 ...

Arrays.toString(data.toByteArray())

보낼 바이트 ..

[B@405217f8

Send (이것은 내 바이트 데이터의 문자열 표현이어야하는 Arrays.toString ()의 결과입니다.이 데이터는 와이어를 통해 전송됩니다) :

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

파이썬 쪽에서 파이썬 서버는 호출자에게 문자열을 반환합니다 (볼 수있는 것은 서버에 보낸 문자열과 같습니다)

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

서버는이 데이터를 클라이언트로 반환해야합니다.

클라이언트가 (문자열로)받는 응답은 다음과 같습니다.

[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]

받은 문자열을 바이트로 되 돌리는 방법을 알 수없는 것 같습니다.]

내가 시도하는 것처럼 보이는 것은 다음과 같은 바이트 배열을 얻는 것입니다 ...

[91, 45, 52, 55, 44, 32, 49, 44, 32, 49, 54, 44, 32, 56, 52, 44, 32, 50, 44, 32, 49, 48, 49, 44, 32, 49, 49, 48, 44, 32, 56, 51, 44, 32, 49, 49, 49, 44, 32, 49, 48, 57, 44, 32, 49, 48, 49, 44, 32, 51, 50, 44, 32, 55, 56, 44, 32, 55, 48, 44, 32, 54, 55, 44, 32, 51, 50, 44, 32, 54, 56, 44, 32, 57, 55, 44, 32, 49, 49, 54, 44, 32, 57, 55, 93]

또는 다음과 같은 바이트 표현을 얻을 수 있습니다.

B@2a80d889

둘 다 내 보낸 데이터와 다릅니다 ... 나는 정말 간단한 것을 놓치고 있다고 확신합니다 ....

어떤 도움?

답변:


272

반환 된 문자열을 가져 와서 문자열을 구성 할 수는 없습니다. byte[]더 이상 데이터 형식 이 아니며 이미 문자열입니다. 구문 분석해야합니다. 예를 들면 다음과 같습니다.

String response = "[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]";      // response from the Python script

String[] byteValues = response.substring(1, response.length() - 1).split(",");
byte[] bytes = new byte[byteValues.length];

for (int i=0, len=bytes.length; i<len; i++) {
   bytes[i] = Byte.parseByte(byteValues[i].trim());     
}

String str = new String(bytes);

** 편집 **

당신은 당신이 "라고 질문에서 문제의 힌트를 얻을 Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ..."때문에, 91의 바이트 값이 [너무, [91, 45, ...문자열의 바이트 배열입니다 " [-45, 1, 16, ..."문자열입니다.

이 메소드 Arrays.toString()String지정된 배열 의 표현을 리턴합니다 . 반환 된 값이 더 이상 배열이 아님을 의미합니다. 예를 들면 다음과 같습니다.

byte[] b1 = new byte[] {97, 98, 99};

String s1 = Arrays.toString(b1);
String s2 = new String(b1);

System.out.println(s1);        // -> "[97, 98, 99]"
System.out.println(s2);        // -> "abc";

보다시피 s1, 배열 의 문자열 표현 b1s2유지하고에 포함 된 바이트 의 문자열 표현 을 유지합니다 b1.

이제 문제에서 서버는와 비슷한 문자열을 반환 s1하므로 배열 표현을 다시 얻으려면 반대 생성자 메서드가 필요합니다. s2.getBytes()의 반대 인 경우 의 반대 new String(b1)를 찾아야 Arrays.toString(b1)하므로이 답변의 첫 번째 조각에 붙여 넣은 코드입니다.


대박! 나는 당신이 내가 무엇을했는지 완전히 이해했다고 생각합니다 ... 나는 Java 배경이 아니기 때문에 필요한 변환을 실제로 파악할 수 없었습니다. 정보를 위해 s1을 서버에 보내고 서버가 s1로 응답하고 있습니다 (서버가 s1의 데이터를 수신하고 응답했는지 확인할 수 있습니다). 따라서 Arrays.toString ()의 반대가 필요했습니다. 당신은 제안했습니다 ... 그리고 당신의 해결책은 꽤 대담합니다! 건배!
0909EM

야닉 감사합니다. 그러나 bytes.length의 값이 2046이므로 각 이미지에 대해 2046 번 반복됩니다. 다른 방법이 있습니까?
Gugan February

수신중인 데이터가 실제로 사람이 읽을 수있는 문자열 인 경우 response내 대답 의 변수 값처럼 구문 분석해야하지만 불행히도 아니요, 다른 방법은 없습니다. 가장 좋은 방법은 바이트를 문자열 대신 원시 데이터 (이진) 또는 Base64 문자열로 수신하는 것입니다.이를 기본 256 (이진) 값으로 다시 변환하면됩니다.
Rochon

3
그렇지 않으면 올바른 (완전하지는 않지만) 답변에 추가하려면 : 1) Java에서 String으로 변환되는 모든 byte [] 배열은 문자 집합을 지정해야합니다. byte [] 배열이 UTF-8입니까 아니면 다른 것입니까? 구체적이지 않거나 그것이 무엇인지 알지 못하면 버그가 발생할 수 있습니다. 2) Java는 Big-Endian 인코딩을 사용하지만 M $ 시스템은 Little-Endian을 사용합니다. 문자열 (문자 기반) 인 byte [] 배열을 처리 할 때는 문제가 없습니다. 그러나 byte [] 배열이 숫자를 나타내는 경우 소스 / 대상 시스템의 '환경'이 중요합니다.
Darrell Teague

130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

콘솔에 "cool string"을 출력합니다.

꽤 쉽습니다.


6
너무 많은 다운 보트이지만 설명이 거의 없습니다 ... 내가 말한 내용이 효과가 없습니까? 내가 그것을 사용할 때 효과가 있었고 문제는 바이트에서 문자열로 변환하고 다시 다시 변환하는 방법입니다.
CorayThan

2
이 문제를 해결 한 답변은 실제로 답변으로 표시됩니다. 메모리에서 그것은 당신이 제안한 것처럼 간단하지 않습니다 ... Yanick의 답변을 참조하십시오, 나는 당신이 내가 무엇을 요구했는지 잘못 이해했다고 생각하지만 입력에 감사드립니다.
0909EM

9
@CorayThan 사실 아니요, OP의 질문을 전혀 다루지 않습니다. 당신이 실제로 그것을 통해 읽는 경우, 당신은 byte[]그가 받고 있는 것을 나타냅니다 String; 즉 "[97, 98, 99]"아닙니다 [97, 98, 99]. 즉, 귀하의 답변은이 상황에도 적용되지 않습니다.
b1nary.atr0phy

2
당신의 대답은 Stringbyte[]String. 나는 문제의 요구 사항은 생각 byte[]Stringbyte[].
Wundwin

13
질문에 대한 잘못된 답변 일 수도 있지만 문제를 해결하는 데 도움이되었습니다. 그렇기 때문에 사람들은 다른 사람의 답변을 다운 그레이드하기 전에 조금 더 생각해야합니다. CorayThan 감사합니다!
Roberto Santos

21

제가 한:

고객에게 반환 :

byte[] result = ****encrypted data****;

String str = Base64.encodeBase64String(result);

return str;

고객으로부터 받기 :

 byte[] bytes = Base64.decodeBase64(str);

데이터는 다음 형식으로 전송됩니다.

OpfyN9paAouZ2Pw+gDgGsDWzjIphmaZbUyFx5oRIN1kkQ1tDbgoi84dRfklf1OZVdpAV7TonlTDHBOr93EXIEBoY1vuQnKXaG+CJyIfrCWbEENJ0gOVBr9W3OlFcGsZW5Cf9uirSmx/JLLxTrejZzbgq3lpToYc3vkyPy5Y/oFWYljy/3OcC/S458uZFOc/FfDqWGtT9pTUdxLDOwQ6EMe0oJBlMXm8J2tGnRja4F/aVHfQddha2nUMi6zlvAm8i9KnsWmQG//ok25EHDbrFBP2Ia/6Bx/SGS4skk/0couKwcPVXtTq8qpNh/aYK1mclg7TBKHfF+DHppwd30VULpA== 

7

어떤 Arrays.toString()일은 당신이 ByteArray 각 바이트의 문자열 표현을 만드는 것입니다.

API 문서 배열 API를 확인하십시오

응답 문자열을 원래 바이트 배열로 다시 변환하려면 split(",")또는 무언가 를 사용 하여 컬렉션으로 변환 한 다음 거기에있는 각 개별 항목을 바이트로 변환하여 바이트 배열을 다시 만들어야합니다.


5

바이트 배열을 문자열로 변환하고 문자열을 Java에서 바이트 배열로 다시 변환하는 것은 간단합니다. 올바른 방법으로 '신규'를 사용해야하는시기를 알아야합니다. 다음과 같이 수행 할 수 있습니다.

바이트 배열을 문자열로 변환 :

byte[] bytes = initializeByteArray();
String str = new String(bytes);

문자열을 바이트 배열로 변환 :

String str = "Hello"
byte[] bytes = str.getBytes();

자세한 내용은 다음을 참조하십시오. http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html


2
아니요, 질문을 읽지 않았거나 문제를 이해하지 못했습니다. 당신이 질문이 몇 년 전에 답변
되었음을 주목할 것입니다

3

바이트 배열 ( [B@405217f8) 에서보고있는 출력의 종류는 길이가 0 인 바이트 배열 (예 :)의 출력이기도합니다 new byte[0]. 이 문자열은 일반 컬렉션의 toString()메소드 에서 예상 할 수있는 것처럼 배열의 내용에 대한 설명이 아니라 배열에 대한 참조 인 것 같습니다 .

다른 응답자와 마찬가지로 바이트 배열의 내용에서 문자열을 구성하는 매개 변수를 String허용하는 생성자를 알려 byte[]줍니다. InputStreamTCP 연결에서 바이트를 얻으려면 소켓에서 원시 바이트를 읽을 수 있어야 합니다.

해당 바이트를 이미 String(를 사용하여 InputStreamReader) 읽은 경우 getBytes()함수를 사용하여 문자열을 바이트로 변환 할 수 있습니다 . 원하는 문자 세트를 String 생성자와 getBytes()함수 모두에 전달해야 합니다. 이는 바이트 데이터를로 문자로 변환 할 수있는 경우에만 작동합니다 InputStreamReader.

원시 바이트를 처리하려면이 스트림 리더 계층을 사용하지 않아야합니다.


2

바이트를 바이트로 보내거나 각 바이트를 문자로 변환하고 문자열로 보낼 수 있습니까? 11 바이트 만 보내면 문자열을 그대로 사용하면 문자열에 최소 85자를 사용할 수 있습니다. 바이트의 문자열 표현을 만들 수 있으므로 "[B @ 405217f8"이 되어 파이썬에서 bytes또는 bytearray객체 로 쉽게 변환 할 수 있습니다 . 실패하면 22자를 사용하는 일련의 16 진 숫자 ( "5b42403430353231376638")로 표시 할 수 있으며,이를 사용하여 Python 측에서 쉽게 해독 할 수 있습니다 binascii.unhexlify().


1
[B@405217f8배열의 내용이 아니라 배열의 Java 객체 ID입니다. 객체 ID "파이썬에서 바이트 나 바이트 배열 객체로 쉽게 변환 될 수 없습니다 ". 크기별로 할 수있는 최선의 방법은 byte []를 base64 문자열로 변환하는 것입니다.
보리스 B.

당신은 맞습니다. 나는 0909EM이 객체의 (유형) 주소와 객체의 내용을 구별하기에 충분히 알고 있다고 가정했습니다.
JAB

2

[JDK8]

import java.util.Base64;

문자열로 :

String str = Base64.getEncoder().encode(new byte[]{ -47, 1, 16, ... });

바이트 배열로 :

byte[] bytes = Base64.getDecoder().decode("JVBERi0xLjQKMyAwIG9iago8P...");

1

문자열을 다시 바이트 배열로 변환하려면 사용 String.getBytes()(또는 동등한 Python 함수) 을 사용해야 하며 원래 바이트 배열을 인쇄 할 수 있습니다.


0

아래 코드 API를 사용하여 바이트 코드를 문자열로 바이트 배열로 변환하십시오.

 byte[] byteArray = DatatypeConverter.parseBase64Binary("JVBERi0xLjQKMyAwIG9iago8P...");

-1

[자바 8]

import java.util.Base64;

String dummy= "dummy string";
byte[] byteArray = dummy.getBytes();

byte[] salt = new byte[]{ -47, 1, 16, ... }
String encoded = Base64.getEncoder().encodeToString(salt);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.