Javaバイト配列から文字列からバイト配列


180

バイト[]から文字列、バイト[]からバイト[]への変換の文字列表現を理解しようとしています...バイト[]を文字列に変換して送信し、Webサービス(Pythonで記述)を期待していますデータをクライアントに直接エコーします。

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]

Python側では、Pythonサーバーが呼び出し元に文字列を返します(これは、サーバーに送信した文字列と同じです)

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

ヤニックありがとう。しかし、bytes.lengthの値が2046であるため、各イメージに対して2046回ループします。これを行う他の方法はありますか?
Gugan 2013

あなたが受け取っているデータが実際に人間が読める文字列でありresponse、私の回答の変数の値のように解析する必要がある場合、残念ながら違います。他に方法はありません。最良の方法は、文字列ではなく生データ(バイナリとして)としてバイトを受信することです。あるいはBase64文字列として受信することもできます。これにより、ベース256(バイナリ)値として変換し直すだけで済みます。
Yanick Rochon、2013

3
それ以外は正しい(不完全ではあるが)答えに追加するには:1)JavaでStringに変換されるbyte []配列は、文字セットを指定する必要があります。byte []配列はUTF-8ですか、それとも何か他のものですか?具体的でなかったり、それが何であるかを知らなかったりすると、バグが発生する可能性があります。2)Javaはビッグエンディアンエンコーディングを使用しますが、たとえばM $システムはリトルエンディアンを使用します。文字列(文字ベース)であるbyte []配列を処理する場合、問題はありません。ただし、byte []配列が数値を表す場合、ソース/ターゲットシステムの「エンディアン」が重要です。
ダレルティーグ

130
String coolString = "cool string";

byte[] byteArray = coolString.getBytes();

String reconstitutedString = new String(byteArray);

System.out.println(reconstitutedString);

「クールな文字列」をコンソールに出力します。

とても簡単です。


6
非常に多くの反対票を投じますが、説明はほとんどありません... 私がそれを使用したときにそれは機能しました、そして問題はバイトから文字列に変換し、再び元に戻す方法ですよね?
CorayThan 2013年

2
これを解決した答えは、実際には答えとしてマークされています。記憶からは、あなたが提案したほど単純ではありません...ヤニックの答えを参照してください。
0909EM 2013年

9
@CorayThanいいえ、これはOPの質問にはまったく対応していません。実際にそれを読んだ場合、byte[]彼が受け取っていることがとして表されていることがわかりますString。つまり"[97, 98, 99]"ない[97, 98, 99]。つまり、あなたの答えはこの状況にも当てはまりません。
b1nary.atr0phy 2013年

2
あなたの答えはあるStringbyte[]します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ドキュメントArrays 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[]パラメーターを受け入れるコンストラクターを紹介します。InputStreamTCP接続からバイトを取得したい場合は、ソケットから生のバイトを読み取ることができるはずです。

これらのバイトをString(を使用してInputStreamReader)としてすでに読み取っている場合は、getBytes()関数を使用して文字列をバイトに変換できます。StringコンストラクタとgetBytes()関数の両方に目的の文字セットを渡すようにしてください。これは、バイトデータをによって文字に変換できる場合にのみ機能しInputStreamReaderます。

未加工のバイトを処理する場合は、このストリームリーダーレイヤーの使用を避けてください。


2

バイトをバイトとして送信したり、各バイトを文字に変換して文字列として送信したりできませんか?送信するバイト数が11バイトしかない場合、このようにすると、文字列で85文字以上必要になります。バイトの文字列表現を作成できるため、「[B @ 405217f8」となり、Pythonでbytesまたはbytearrayオブジェクトに簡単に変換できます。これに失敗すると、22文字を使用する一連の16進数( "5b42403430353231376638")として表すことができます。これは、Python側でを使用して簡単にデコードできますbinascii.unhexlify()


1
[B@405217f8配列のコンテンツではなく、配列のJavaオブジェクトIDです。オブジェクトID は、「Pythonでバイトまたはバイト配列オブジェクトに簡単に変換する」ことはできません。サイズごとにできる最善の方法は、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

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