Java Byte Array to String ไปยัง Byte Array


180

ฉันกำลังพยายามทำความเข้าใจกับไบต์ [] ถึงสตริงการแทนสตริงของไบต์ [] ถึงไบต์ [] การแปลง ... ฉันแปลงไบต์ [] เป็นสตริงที่จะส่งฉันก็คาดว่าบริการเว็บของฉัน (เขียนด้วยหลาม) เพื่อสะท้อนข้อมูลกลับไปยังลูกค้าโดยตรง

เมื่อฉันส่งข้อมูลจากแอปพลิเคชัน Java ของฉัน ...

Arrays.toString(data.toByteArray())

ไบต์ที่จะส่ง ..

[B@405217f8

ส่ง (นี่คือผลลัพธ์ของ 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ถือแทนสายของอาร์เรย์ b1ในขณะที่s2ถือเป็นตัวแทนสตริงของไบต์b1ที่มีอยู่ใน

ตอนนี้ในปัญหาของคุณเซิร์ฟเวอร์ของคุณส่งคืนสตริงที่คล้ายกับs1ดังนั้นเพื่อให้ได้การแทนอาเรย์กลับมาคุณต้องใช้วิธีการสร้างที่ตรงกันข้าม หากs2.getBytes()ตรงกันข้ามnew String(b1)คุณต้องหาสิ่งที่ตรงกันข้ามArrays.toString(b1)ดังนั้นรหัสที่ฉันวางในตัวอย่างแรกของคำตอบนี้


! น่ากลัว ฉันคิดว่าคุณเข้าใจในสิ่งที่ฉันเป็นหลังจากนั้น ... ฉันไม่ได้มาจากพื้นหลังของ Java ดังนั้นฉันจึงไม่สามารถเข้าใจการแปลงที่ฉันต้องการได้ สำหรับข้อมูลฉันกำลังส่ง s1 ไปยังเซิร์ฟเวอร์และเซิร์ฟเวอร์กำลังตอบกลับด้วย s1 (ฉันสามารถตรวจสอบว่าเซิร์ฟเวอร์ได้รับและตอบกลับด้วยข้อมูลใน s1) ดังนั้นฉันจึงต้องการตรงกันข้ามกับ Arrays.toString () เป็น คุณแนะนำ ... และวิธีการแก้ปัญหาของคุณค่อนข้างดีทีเดียว! ไชโย!
0909EM

ขอบคุณ Yanick แต่มันวนซ้ำ 2046 เท่าสำหรับแต่ละอิมเมจเนื่องจากค่าของไบต์ความยาวคือ 2046 มีวิธีอื่นที่จะทำเช่นนี้หรือไม่?
Gugan

หากข้อมูลที่คุณได้รับคือจริงๆสตริงการอ่านของมนุษย์ที่จะต้องมีการแยกวิเคราะห์เช่นค่าของตัวแปรresponseในคำตอบของฉันแล้วน่าเสียดายที่ไม่มีไม่มีวิธีอื่น ๆ วิธีที่ดีที่สุดคือให้คุณรับไบต์เป็นข้อมูลดิบ (เป็นไบนารี) แทนที่จะเป็นสตริงหรืออาจเป็นสตริง Base64 ซึ่งคุณจะต้องแปลงเป็นค่าฐาน 256 (ไบนารี) เท่านั้น
Yanick Rochon

3
เพื่อเพิ่มสิ่งที่เป็นอย่างอื่นคำตอบที่ถูกต้อง (แม้ว่าจะไม่สมบูรณ์): 1) ใด ๆ ไบต์ [] อาร์เรย์ใด ๆ ที่ถูกแปลงเป็นสตริงใน Java ควรระบุชุดอักขระ ไบต์ [] เป็นอาร์เรย์ UTF-8 หรืออย่างอื่นหรือไม่ ไม่เจาะจงหรือรู้ว่ามันคืออะไรสามารถสร้างบั๊กได้ 2) Java ใช้การเข้ารหัส Big-Endian แต่ใช้ระบบ M $ เช่นใช้ Little-Endian เมื่อจัดการกับไบต์ [] อาร์เรย์ที่เป็นสตริง (อิงตามตัวอักษร) จะไม่มีปัญหา อย่างไรก็ตามหากอาร์เรย์ byte [] แทนตัวเลขตัวเลข 'endianess' ของระบบต้นทาง / ปลายทางนั้นสำคัญ
Darrell Teague

130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

เอาต์พุตนั้น "สตริงเย็น" ไปที่คอนโซล

มันค่อนข้างง่ายที่จะสาป


6
Downvotes มากมาย แต่มีคำอธิบายน้อยมาก ... สิ่งที่ฉันพูดไม่ทำงานใช่ไหม มันใช้งานได้เมื่อฉันใช้มันและคำถามคือวิธีการแปลงจากไบต์เป็นสตริงและกลับมาอีกครั้งใช่มั้ย
CorayThan

2
คำตอบที่แก้ไขนี้ถูกทำเครื่องหมายเป็นคำตอบจริง ๆ จากความทรงจำมันไม่ง่ายอย่างที่คุณแนะนำ ... ดูคำตอบของ Yanick ฉันคิดว่าคุณเข้าใจผิดในสิ่งที่ฉันขอ แต่ขอบคุณสำหรับอินพุต
0909EM

9
@CorayThan จริง ๆ แล้วมันไม่ได้ตอบคำถามของ OP เลย หากคุณอ่านผ่านจริงคุณจะเห็นว่าbyte[]เขาได้รับเป็นตัวแทนString; คือไม่ได้"[97, 98, 99]" [97, 98, 99]ความหมายคำตอบของคุณไม่ได้ใช้กับสถานการณ์นี้
b1nary.atr0phy

2
คำตอบของคุณคือStringการที่จะbyte[] Stringผมคิดว่าต้องการคำถามคือbyte[]จะไปString byte[]
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 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
ไม่คุณไม่ได้อ่านคำถามหรือบางทีคุณไม่เข้าใจปัญหา ในขณะที่คุณจะทราบว่าคำถามนั้นได้รับคำตอบเมื่อหลายปีที่ผ่านมา ...
0909EM

3

ชนิดของเอาต์พุตที่คุณเห็นจากอาร์เรย์ไบต์ ( [B@405217f8) ของคุณเป็นเอาต์พุตสำหรับอาร์เรย์ไบต์ที่มีความยาวเป็นศูนย์ (เช่นnew byte[0]) ดูเหมือนว่าสายนี้คือการอ้างอิงไปยังอาร์เรย์มากกว่าคำอธิบายของเนื้อหาของอาร์เรย์เหมือนที่เราอาจคาดหวังจากtoString()วิธีการของคอลเลกชันปกติ

เช่นเดียวกับผู้ตอบแบบสอบถามคนอื่น ๆ ฉันจะชี้ให้คุณไปที่ตัวStringสร้างที่ยอมรับbyte[]พารามิเตอร์เพื่อสร้างสตริงจากเนื้อหาของอาร์เรย์ไบต์ คุณควรจะสามารถอ่านไบต์ดิบจากซ็อกเก็ตInputStreamถ้าคุณต้องการรับไบต์จากการเชื่อมต่อ TCP

หากคุณได้อ่านไบต์เหล่านั้นเป็นString(โดยใช้InputStreamReader) แล้วสตริงสามารถแปลงเป็นไบต์โดยใช้getBytes()ฟังก์ชั่น ให้แน่ใจว่าจะผ่านในชุดตัวอักษรที่คุณต้องการทั้งตัวสร้าง String และฟังก์ชั่นและงานนี้จะมีเพียงหากข้อมูลไบต์สามารถแปลงเป็นตัวอักษรโดยgetBytes()InputStreamReader

หากคุณต้องการจัดการกับไบต์ดิบคุณควรหลีกเลี่ยงการใช้เลเยอร์ตัวอ่านสตรีมนี้


2

คุณไม่เพียงแค่ส่งไบต์เป็นไบต์หรือแปลงแต่ละไบต์เป็นอักขระและส่งเป็นสตริงได้หรือไม่ การทำเช่นนี้คุณจะต้องมีอักขระอย่างน้อย 85 ตัวในสตริงเมื่อคุณมี 11 ไบต์เท่านั้นที่จะส่ง คุณสามารถสร้างการแสดงสตริงของไบต์ดังนั้นมันจะเป็น "[B @ 405217f8" ซึ่งสามารถแปลงเป็นbytesหรือbytearrayวัตถุใน Python ได้อย่างง่ายดาย ความล้มเหลวที่คุณสามารถเป็นตัวแทนของพวกเขาเป็นชุดของตัวเลขฐานสิบหก ( "5b42403430353231376638") สละเพิ่มขึ้น 22 binascii.unhexlify()ตัวอักษรที่สามารถถอดรหัสได้อย่างง่ายดายบนด้านหลามใช้


1
[B@405217f8เป็น ID อ็อบเจ็กต์ Java ของอาร์เรย์ไม่ใช่เนื้อหาของอาร์เรย์ รหัสวัตถุแน่นอนไม่สามารถ "แปลงเป็นไบต์หรือวัตถุไบต์ใน python" ได้อย่างง่ายดาย วิธีที่ดีที่สุดที่คุณสามารถทำได้คือการแปลงไบต์ [] ให้เป็นสตริงเบส 64
Boris 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 ด้านล่างเพื่อแปลง bytecode เป็นสตริงเป็นอาร์เรย์ไบต์

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

-1

[JAVA 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.