Java Byte Array to String to Byte Array


180

Tôi đang cố gắng hiểu một byte [] thành chuỗi, biểu diễn chuỗi của byte [] sang byte [] chuyển đổi ... Tôi chuyển đổi byte [] của mình thành một chuỗi để gửi, sau đó tôi mong đợi dịch vụ web của mình (được viết bằng python) để lặp lại dữ liệu trở lại máy khách.

Khi tôi gửi dữ liệu từ ứng dụng Java của mình ...

Arrays.toString(data.toByteArray())

Byte để gửi ..

[B@405217f8

Gửi (Đây là kết quả của Arrays.toString () sẽ là một chuỗi đại diện cho dữ liệu byte của tôi, dữ liệu này sẽ được gửi qua dây):

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

Về phía python, máy chủ python trả về một chuỗi cho người gọi (mà tôi có thể thấy giống như chuỗi tôi đã gửi đến máy chủ

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

Máy chủ sẽ trả lại dữ liệu này cho khách hàng, nơi nó có thể được xác minh.

Phản hồi mà khách hàng của tôi nhận được (dưới dạng một chuỗi) trông giống như

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

Tôi dường như không thể tìm ra làm thế nào để đưa chuỗi nhận được trở lại thành một byte []

Bất cứ điều gì tôi dường như cố gắng, cuối cùng tôi cũng nhận được một mảng byte trông như sau ...

[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]

hoặc tôi có thể nhận được một đại diện byte như sau:

B@2a80d889

Cả hai thứ này đều khác với dữ liệu đã gửi của tôi ... Tôi chắc chắn tôi đang thiếu thứ gì đó thực sự đơn giản ....

Có ai giúp được không?!

Câu trả lời:


272

Bạn không thể lấy chuỗi trả về và tạo chuỗi từ nó ... nó không phải là byte[]kiểu dữ liệu nữa, nó đã là một chuỗi; bạn cần phân tích nó Ví dụ :

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);

** CHỈNH SỬA **

Bạn nhận được một gợi ý về vấn đề của bạn trong câu hỏi của bạn, nơi bạn nói " Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ...", bởi vì 91là giá trị byte cho [, nên [91, 45, ...mảng byte của chuỗi " [-45, 1, 16, ..." là chuỗi.

Phương thức Arrays.toString()sẽ trả về một Stringđại diện của mảng đã chỉ định; có nghĩa là giá trị trả về sẽ không còn là một mảng nữa. Ví dụ :

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";

Như bạn có thể thấy, s1giữ biểu diễn chuỗi của mảng b1 , trong khi s2giữ biểu diễn chuỗi của các byte có trongb1 .

Bây giờ, trong vấn đề của bạn, máy chủ của bạn trả về một chuỗi tương tự s1, do đó để lấy lại biểu diễn mảng, bạn cần phương thức xây dựng ngược lại. Nếu s2.getBytes()ngược lại new String(b1), bạn cần tìm ngược lại Arrays.toString(b1), do đó mã tôi đã dán trong đoạn đầu tiên của câu trả lời này.


Tuyệt vời! Tôi nghĩ rằng bạn đã hoàn toàn hiểu những gì tôi đã có sau ... Tôi không đến từ nền tảng Java, vì vậy tôi thực sự không thể tìm ra chuyển đổi tôi cần. Chỉ để biết thông tin, tôi đang gửi s1 đến máy chủ và máy chủ đang trả lời s1 (Tôi có thể xác minh rằng máy chủ đã nhận và trả lời dữ liệu trong s1), vì vậy tôi cần ngược lại với Arrays.toString () bạn đề nghị ... VÀ giải pháp của bạn khá tốt! Chúc mừng!
0909EM

Cảm ơn bạn Yanick. Nhưng nó lặp lại 2046 lần cho mỗi hình ảnh vì giá trị của byte.length là 2046. Có phương pháp nào khác để làm điều này không?
Gugan

Nếu dữ liệu bạn đang nhận thực sự là một chuỗi có thể đọc được của con người cần được phân tích cú pháp như giá trị của biến responsetrong câu trả lời của tôi, thì thật không may, không có cách nào khác. Cách tốt nhất là bạn nhận các byte dưới dạng dữ liệu thô (dưới dạng nhị phân) thay vì chuỗi, hoặc thậm chí là chuỗi Base64, chỉ yêu cầu bạn chuyển đổi lại thành giá trị 256 (nhị phân) cơ bản.
Yanick Rochon

3
Để thêm vào câu trả lời đúng (mặc dù không đầy đủ): 1) Bất kỳ mảng byte [] nào được chuyển đổi thành Chuỗi trong Java phải chỉ định bộ ký tự. Là mảng byte [] UTF-8 hay cái gì khác? Không cụ thể hoặc biết những gì nó có thể tạo ra lỗi. 2) Java sử dụng mã hóa Big-Endian nhưng các hệ thống M $ chẳng hạn sử dụng Little-Endian. Khi xử lý các mảng byte [] là các chuỗi (dựa trên ký tự), không có vấn đề gì. Tuy nhiên, nếu mảng byte [] đại diện cho một số, thì 'endianess' của hệ thống nguồn / đích là vấn đề.
Darrell Teague

130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

Điều đó xuất ra "chuỗi mát mẻ" cho bàn điều khiển.

Nó khá dễ dàng.


6
Rất nhiều downvote, nhưng rất ít lời giải thích ... Liệu những gì tôi nói không hoạt động? Nó hoạt động khi tôi sử dụng nó, và câu hỏi là làm thế nào để chuyển đổi từ byte thành chuỗi và trở lại, phải không?
CorayThan

2
Câu trả lời đã giải quyết điều này thực sự được đánh dấu là câu trả lời. Từ bộ nhớ, nó không đơn giản như bạn đã đề xuất ... Xem câu trả lời của Yanick, tôi nghĩ rằng bạn đã hiểu sai những gì tôi đang hỏi, nhưng cảm ơn vì đầu vào.
0909EM

9
@CorayThan Thật ra không, điều này hoàn toàn không giải quyết được câu hỏi của OP. Nếu bạn thực sự đọc thông qua nó, bạn sẽ thấy rằng byte[]anh ấy đang nhận được đại diện như một String; tức là "[97, 98, 99]"không [97, 98, 99]. Có nghĩa là, câu trả lời của bạn thậm chí không áp dụng cho tình huống này.
b1nary.atr0phy

2
Câu trả lời của bạn là Stringđể byte[]đến String. Tôi nghĩ rằng yêu cầu câu hỏi là byte[]để Stringđến byte[].
Wundwin Sinh

13
Thậm chí có thể là câu trả lời sai cho câu hỏi được hỏi, nhưng nó đã giúp tôi giải quyết một vấn đề. Đó là lý do tại sao mọi người nên suy nghĩ nhiều hơn một chút trước khi hạ cấp người khác trả lời. Cảm ơn bạn CorayThan!
Roberto Santos

21

Tôi đã làm gì:

trả lại cho khách hàng:

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

String str = Base64.encodeBase64String(result);

return str;

nhận từ khách hàng:

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

dữ liệu của bạn sẽ được chuyển theo định dạng này:

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

7

Điều gì Arrays.toString()làm là tạo một chuỗi đại diện cho từng byte riêng lẻ trong byteArray của bạn.

Vui lòng kiểm tra tài liệu API Mảng API

Để chuyển đổi chuỗi phản hồi của bạn trở lại mảng byte ban đầu, bạn phải sử dụng split(",")hoặc một cái gì đó và chuyển đổi nó thành một bộ sưu tập và sau đó chuyển đổi từng mục riêng lẻ trong đó thành một byte để tạo lại mảng byte của bạn.


5

Thật đơn giản để chuyển đổi mảng byte thành chuỗi và chuỗi trở lại mảng byte trong java. chúng ta cần biết khi nào nên sử dụng 'mới' theo đúng cách. Nó có thể được thực hiện như sau:

mảng byte chuyển đổi chuỗi:

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

Chuyển đổi chuỗi thành chuỗi byte:

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

Để biết thêm chi tiết, xem tại: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-opes.html


2
Không, bạn chưa đọc câu hỏi hoặc có lẽ bạn chưa hiểu vấn đề. Như bạn sẽ lưu ý câu hỏi đã được trả lời nhiều năm trước ...
0909EM

3

Loại đầu ra mà bạn đang thấy từ mảng byte của bạn ( [B@405217f8) cũng là đầu ra cho mảng byte có độ dài bằng không (nghĩa là new byte[0]). Dường như chuỗi này là một tham chiếu đến mảng chứ không phải là một mô tả về nội dung của mảng như chúng ta có thể mong đợi từ một bộ sưu tập thông thườngtoString() phương thức .

Cũng như những người trả lời khác, tôi sẽ chỉ cho bạn các hàm Stringtạo chấp nhận một byte[]tham số để xây dựng một chuỗi từ nội dung của một mảng byte. Bạn sẽ có thể đọc byte thô từ ổ cắm InputStreamnếu bạn muốn lấy byte từ kết nối TCP.

Nếu bạn đã đọc các byte đó dưới dạng String(sử dụng một InputStreamReader), thì chuỗi có thể được chuyển đổi thành byte bằng getBytes()hàm. Hãy chắc chắn chuyển bộ ký tự mong muốn của bạn cho cả getBytes()hàm và hàm tạo Chuỗi và điều này sẽ chỉ hoạt động nếu dữ liệu byte có thể được chuyển đổi thành ký tự bởi InputStreamReader.

Nếu bạn muốn xử lý các byte thô, bạn thực sự nên tránh sử dụng lớp trình đọc luồng này.


2

Bạn có thể không chỉ gửi các byte dưới dạng byte hoặc chuyển đổi từng byte thành một ký tự và gửi dưới dạng chuỗi không? Làm như bạn sẽ mất tối thiểu 85 ký tự trong chuỗi, khi bạn chỉ có 11 byte để gửi. Bạn có thể tạo một chuỗi đại diện cho các byte, vì vậy nó sẽ là "[B @ 405217f8", có thể dễ dàng chuyển đổi thành một byteshoặc một bytearrayđối tượng trong Python. Không, bạn có thể biểu diễn chúng dưới dạng một loạt các chữ số thập lục phân ("5b42403430353231376638") chiếm 22 ký tự, có thể dễ dàng giải mã ở phía Python bằng cách sử dụng binascii.unhexlify().


1
[B@405217f8là ID đối tượng Java của mảng, không phải nội dung của mảng. ID đối tượng chắc chắn không thể "dễ dàng được chuyển đổi thành một đối tượng byte hoặc bytearray trong python". Cách tốt nhất bạn có thể thực hiện theo kích thước là chuyển đổi byte [] thành chuỗi base64.
Boris B.

Bạn đã đúng, tôi ngây thơ giả định 0909EM biết đủ để phân biệt giữa địa chỉ (đã gõ) của một đối tượng và nội dung của đối tượng.
JAB

2

[JDK8]

import java.util.Base64;

Để chuỗi:

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

Để mảng byte:

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

1

Nếu bạn muốn chuyển đổi chuỗi trở lại thành một mảng byte, bạn sẽ cần sử dụng String.getBytes()(hoặc hàm Python tương đương) và điều này sẽ cho phép bạn in ra mảng byte gốc.


0

Sử dụng API mã bên dưới để chuyển đổi mã byte thành chuỗi thành mảng Byte.

 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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.