Java Bayt Dizisi Dizeden Bayt Dizisine


180

Ben bir bayt [] dizeye, bayt [] bayt [] dönüşüm dizisi temsil anlamaya çalışıyorum ... Ben göndermek için bir dizeye benim bayt [] dönüştürmek, sonra web hizmeti (python ile yazılmış) bekliyoruz Verileri doğrudan istemciye yansıtır.

Verileri Java uygulamamdan gönderdiğimde ...

Arrays.toString(data.toByteArray())

Gönderilecek bayt ..

[B@405217f8

Gönder (Bu, bayt verilerimin dize olarak temsil edilmesi gereken Arrays.toString () işlevinin sonucudur, bu veriler kablo üzerinden gönderilir):

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

Python tarafında, python sunucusu arayana bir dize döndürür (görebildiğim sunucuya gönderdiğim dize ile aynıdır)

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

Sunucunun bu verileri, doğrulanabileceği istemciye döndürmesi gerekir.

Müvekkilimin aldığı cevap (dize olarak)

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

Alınan dizeyi bir bayta geri nasıl alacağımı anlayamıyorum []

Denemek için ne olursa olsun ben aşağıdaki gibi görünen bir bayt dizi elde sonunda ...

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

veya aşağıdaki gibi bir bayt temsili alabilirim:

B@2a80d889

Bunların her ikisi de gönderilen verilerimden farklı ... Eminim gerçekten basit bir şey eksik ....

Herhangi bir yardım?!

Yanıtlar:


272

Döndürülen dizeyi alıp ondan bir dize oluşturamazsınız ... byte[]artık bir veri türü değil, zaten bir dize; ayrıştırmanız gerekiyor. Örneğin :

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

** DÜZENLE **

Sorunuzda " Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ..." dediğiniz bir sorun ipucu alıyorsunuz , çünkü 91bayt değeri [, [91, 45, ..." [-45, 1, 16, ..." dizesinin bayt dizisi de öyle .

Yöntem , belirtilen dizinin Arrays.toString()bir Stringtemsilini döndürür ; yani döndürülen değer artık bir dizi olmayacak. Örneğin :

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

Gördüğünüz gibi, s1dize temsilini tutan dizinin b1 ederken, s2dize temsilini tutan bayt içerdiği b1.

Şimdi, sorununuzda, sunucunuz benzer bir dize döndürür s1, bu nedenle dizi temsilini geri almak için ters yapıcı yöntemine ihtiyacınız vardır. Bunun s2.getBytes()tam tersi ise, tam tersini new String(b1)bulmanız gerekir Arrays.toString(b1), bu nedenle bu cevabın ilk kod parçasına yapıştırdığım kod.


Müthiş! Sanırım neyin peşinde olduğumu tamamen anladın ... Java geçmişinden değilim, bu yüzden ihtiyacım olan dönüşümü gerçekten anlayamadım. Sadece bilgi için, sunucuya s1 gönderiyorum ve sunucu s1 ile cevap veriyor (sunucunun s1'deki verilerle yanıtlandığını doğrulayabiliyorum), bu yüzden Arrays.toString () önerdin ... VE çözümün çok iyi! Şerefe!
0909EM

Teşekkürler Yanick. Ancak bayt.length değeri 2046 olduğu için her görüntü için 2046 kez dönüyor. Bunu yapmak için başka bir yöntem var mı?
Gugan

Aldığınız veriler, cevabımdaki değişkenin değeri gibi ayrıştırılması gereken gerçekten okunabilir bir dize ise response, maalesef hayır, başka bir yol yoktur. En iyi yol, baytları bir dize yerine ham veri (ikili olarak) veya belki de sadece temel 256 (ikili) değeri olarak dönüştürmenizi gerektiren bir Base64 dizesi olarak almanızdır.
Yanick Rochon

3
Başka türlü doğru (eksik olsa da) yanıtı eklemek için: 1) Java'da bir String'e dönüştürülen tüm bayt [] dizileri karakter kümesini belirtmelidir. Bayt [] dizisi UTF-8 veya başka bir şey mi? Spesifik olmamak ya da ne olduğunu bilmek hatalar yaratabilir. 2) Java, Big-Endian kodlaması kullanır ancak M $ sistemleri örneğin Little-Endian kullanır. Dizeler (karakter tabanlı) olan bayt [] dizileriyle uğraşırken, sorun değil. Bununla birlikte, byte [] dizisi bir sayıyı temsil ediyorsa, kaynak / hedef sistemlerin 'endianess'i önemlidir.
Darrell Teague

130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

Konsola "cool string" çıktısı verir.

Oldukça kolay.


6
Pek çok downvotes, ama çok az açıklama ... Söylediklerim işe yaramıyor mu? Onu kullandığımda işe yaradı ve soru baytlardan dizelere ve tekrar nasıl dönüştürüleceği, değil mi?
CorayThan

2
Bunu çözen cevap aslında cevap olarak işaretlenmiştir. Bellekten önerdiğiniz kadar basit değil ... Yanick'in cevabına bakın, bence ne istediğimi yanlış anladınız, ama girdi için teşekkürler.
0909EM

9
@CorayThan Aslında hayır, bu OP'nin sorusuna hiç değinmiyor. Aslında bunun aracılığıyla okursanız görürsünüz byte[]o bir olarak temsil edilir alıyor String; yani "[97, 98, 99]"değil [97, 98, 99]. Yani, cevabınız bu durum için bile geçerli değil.
b1nary.atr0phy

2
Cevabınız Stringiçin byte[]için String. Ben soru gereksinimi olduğunu düşünüyorum byte[]etmek Stringiçin byte[].
Wundwin

13
Sorulan soru için yanlış yanıt bile olabilir, ancak bir sorunu çözmeme yardımcı oldu. Bu yüzden insanlar bir başkasının cevabını indirmeden önce biraz daha düşünmelidir. Teşekkürler CorayThan!
Roberto Santos

21

Ben ne yaptım:

müşterilere dönüş:

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

String str = Base64.encodeBase64String(result);

return str;

müşterilerden almak:

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

verileriniz şu biçimde aktarılacaktır:

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

7

Ne Arrays.toString()yapar? ByteArray öğenizdeki her bir baytın dize olarak temsilini oluşturmaktır.

Lütfen API belgelerine bakın Arrays API'sı

Yanıt dizenizi orijinal bayt dizisine geri dönüştürmek için split(",")veya bir şey kullanmanız ve bir koleksiyona dönüştürmeniz ve ardından bayt dizinizi yeniden oluşturmak için oradaki her bir öğeyi bir bayta dönüştürmeniz gerekir.


5

Onun basit byte dizi dize ve dize geri byte diziye java dönüştürmek için. 'yeni' yi ne zaman doğru kullanacağımızı bilmemiz gerekir. Aşağıdaki gibi yapılabilir:

diziden dizeye dönüştürme:

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

Dizeden bayta dizi dönüşümü:

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

Daha fazla ayrıntı için şu adrese bakın: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html


2
Hayır, soruyu okumadınız veya belki de sorunu anlamamışsınızdır. Sorunun belirtildiği gibi yıllar önce cevaplandı ...
0909EM

3

Bayt dizinizden ( [B@405217f8) gördüğünüz çıktı türü de sıfır uzunluklu bayt dizisi (yani new byte[0]) için bir çıktıdır . Bu dize, normal bir koleksiyonun toString()yönteminden beklediğimiz gibi dizinin içeriğinin açıklaması yerine diziye bir referans gibi görünüyor .

Diğer katılımcılarda olduğu gibi, sizi bir bayt dizisinin içeriğinden bir dize oluşturmak için Stringbir byte[]parametre kabul eden kuruculara işaret ederdim . InputStreamTCP bağlantısından bayt almak istiyorsanız , bir yuvadaki ham baytları okuyabilmeniz gerekir .

Bu baytları String(a kullanarak InputStreamReader) zaten okuduysanız , dize getBytes()işlev kullanılarak baytlara dönüştürülebilir . İstediğiniz karakter kümesini hem String yapıcısına hem de getBytes()işlevlere ilettiğinizden emin olun; bu yalnızca bayt verileri tarafından karakterlere dönüştürülebiliyorsa çalışır InputStreamReader.

Ham baytlarla uğraşmak istiyorsanız, bu akış okuyucu katmanını kullanmaktan gerçekten kaçınmalısınız.


2

Baytları sadece bayt olarak gönderemez veya her baytı bir karaktere dönüştürüp dize olarak gönderemez misiniz? Gönderdiğiniz gibi yapmanız, gönderilecek yalnızca 11 baytınız olduğunda dizede en az 85 karakter alacaktır. Baytların dize olarak temsilini oluşturabilirsiniz, bu nedenle "[B @ 405217f8" olur ve bu Python'daki bir nesneye bytesveya bytearraynesneye kolayca dönüştürülebilir . Bunu yapmazsanız, bunları Python tarafında kolayca çözülebilen 22 karakter alan bir dizi onaltılık basamak ("5b42403430353231376638") olarak temsil edebilirsiniz binascii.unhexlify().


1
[B@405217f8dizinin içeriği değil, dizinin Java nesne kimliğidir. Nesne kimliği kesinlikle olamaz "kolayca bayt veya python ByteArray nesnesine dönüştürülür". Size göre yapabileceğiniz en iyi şey, bayt [] öğesini bir base64 dizesine dönüştürmektir.
Boris B.

Haklısın, saf bir şekilde 0909EM'in bir nesnenin (yazılan) adresi ile nesnenin içeriği arasında ayrım yapabileceğini biliyordum.
JAB

2

[JDK8]

import java.util.Base64;

Dizmek için:

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

Bayt dizisine:

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

1

Dizeyi tekrar bir bayt dizisine dönüştürmek istiyorsanız kullanmanız gerekir String.getBytes()(veya eşdeğer Python işlevi) ve bu, orijinal bayt dizisini yazdırmanıza izin verir.


0

Bayt kodunu dizgi olarak Bayt dizisine dönüştürmek için aşağıdaki kod API'sını kullanın.

 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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.