2013-08-21 7 views
15

バイト配列をスライスして配列の最初の部分を切り詰めようとしています。私はByteBufferを使用していますが、期待通りの動作をしません。Javaでバイト配列をスライス

byte[] myArray = new byte[10]; 
ByteBuffer buf = ByteBuffer.wrap(myArray); 
buf.position(5); 
ByteBuffer slicedBuf = buf.slice(); 
byte[] newArray = slicedBuf.array(); 

私のByteBufferの最後の部分だけを含むnewArrayのサイズは5と予想されます。代わりに、完全なバイト配列が返されます。私はこれが "バッキングバッファー"がすべて同じものであることを理解しています。

どのようにしてアレイの必要な部分のみをスライスできますか?

EDIT:追加されたコンテキスト

バイトはネットワークから受信されます。私はすでに、パラメータとしてバイト配列を受け取り、SHA1ハッシュを計算する機能を持っている

[ SHA1 hash ] [ data... lots of it ]

:バッファがこのように形成されています。私が望むのは、予想されるハッシュなしでデータだけを渡すためにフルバッファをスライスすることです。

+0

ハッシュ関数を書いていないのであれば、コピーを避けたい場合には、一度 'byte []'の中にすべてが入っていれば固まってしまいます。ネットワークからハッシュを1つの配列に、データを別の配列に読み込むのはなぜですか? –

答えて

45

Arrays.copyOfRangeメソッドを使用できます。例:あなたが作成した

// slice from index 5 to index 9 
byte[] slice = Arrays.copyOfRange(myArray, 5, 10); 
+0

ありがとうございます。コピーせずにこれを行う方法があるかどうか知っていますか?私の配列は多くのメガバイトに達するので、できるだけコピーを避けることを好むでしょう。 – Eric

+0

バイト配列のバイトは、異なる配列によって再利用することはできません。この目的のためにByteBufferクラスがあります。または、配列に加えてスライスのオフセットと長さを受け入れるようにSHA1関数を変更します。 – Joni

+0

ハッシュアルゴリズムはjavax.crypto.macであるため変更できないと思います。私はそれに渡されるパラメータを制御できません。 – Eric

5

ByteBufferは、その配列によってバックアップされています。あなたが効果的にそのデータの特定ビュー受信slice()呼び出すとき:

をそのコンテンツのバッファのコンテンツの共有のサブシーケンスである新しいバイトのバッファを作成します。

array()を呼び出すと、ByteBufferが返され、その全体がバッキング配列として返されます。あなたができること、ビューからすべてのバイトを抽出するために

、:

byte[] bytes = new byte[slicedBuf.remaining()]; 
slicedBuf.read(bytes); 

そのビューからのバイトが新しい配列にコピーされます。

編集以下のコメントから追加する:それはあなたがやってに興味を持っているすべてを別のbyte[]に1 byte[]からバイトをコピーしている場合は、ByteBufferを使用する理由はありませんということは注目に値します。単純にバイトをコピーします。

+0

基本的に、あなたの答えにByteBufferという単語が存在すれば、それは悪い答えです。人形のためのJoniの答えを参照してください(そして受け入れられるのはIMHOのみです)。 – Bohemian

+2

私は彼の意図の解釈ではなく、OPの質問に答えました。さらに、あなたの答えに*理由*のことを説明する内容がない場合、それは悪い答えです。 –

+0

はい、あなたの答えに感謝します。私はCからコードを移植していますが、そこにはコピーがありません。ポインタの操作だけなので、Javaで何か同じことを期待していました。私の配列は多くのメガバイトに達するのでコピーはかなり無駄です – Eric