2012-03-22 16 views
0

SocketChannelからBlockBufferにBLOCKSIZE(たとえば512)バイトのブロックを連続的に読み取ります。私はバイト[]にByteBufferのコンテンツを追加して、次のラウンドに行きたいと思います。結果は、SocketChannelから読み取られたすべてのバイトを含むbyte []に​​なります。ByteBufferからbyte []への書き込みはbyte []に​​書き込みません

これでSystem.arraycopy(...)が正常に動作します。しかし、私がByteBufferのget(result、offset、length)を使うと、何も書き込まれません。結果の配列値はゼロのままです。

なぜですか?

public final static int BLOCKSIZE = 512; 

    public byte[] getReceivedData() { 
    int offset = 0, read; 
    byte[] result = {}; 
    ByteBuffer buffer = ByteBuffer.allocate(BLOCKSIZE); 
    try { 
     while (true) { 
     read = _socketChannel.read(buffer); 
     if (read < 1) { 
      // Nothing was read. 
      break; 
     } 

     // Enlarge result so we can append the bytes we just read. 
     result = Arrays.copyOf(result, result.length + read); 

     // This works as expected. 
     System.arraycopy(buffer.array(), 0, result, offset * BLOCKSIZE, read); 

     // With this, however, nothing is written to result. Why? 
     buffer.get(result, offset * BLOCKSIZE, read); 

     if (read < BLOCKSIZE) { 
      // Nothing left to read from _socketChannel. 
      break; 
     } 

     buffer.clear(); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return result; 
    } 

EDIT:

私も、offset++が欠落していた気づきました。だから、BLOCKSIZEバイト以上がチャンネルに残っていると、事態が悪くなってしまいます...

とにかく、ByteArrayOutputStreamは本当に簡単になりますので、私はそれを使用することにしました。

の作業コード:

public byte[] getReceivedData() { 
    int read; 
    ByteArrayOutputStream result = new ByteArrayOutputStream(); 
    ByteBuffer buffer = ByteBuffer.allocate(BLOCKSIZE); 
    try { 
     while (true) { 
     buffer.clear(); 
     read = _socketChannel.read(buffer); 
     if (read < 1) { 
      break; 
     } 
     result.write(buffer.array(), 0, read); 
     if (read < BLOCKSIZE) { 
      break; 
     } 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return result.toByteArray(); 
    } 

答えて

2
あなたは get()flip()バッファに必要

、その後compact()それを。

read == -1の場合は、ループから脱出するだけでなく、チャンネルを閉じる必要があります。

+0

フリップ()は、トリックをしました、ありがとう。私は 'compact()'は必要ないと思う。バッファからすべてのものを 'get()'した後、コンパイルする必要はありませんし、とにかく各繰り返しで 'clear()'します。また、チャンネルを閉じるヒントをありがとう。私はチャンネルが開いたままであることを意識しています。クライアントはいつでも新しいデータを送信できます。 – riha

+0

@riha間違っています。あなたが-1を取得した後でクライアントはあなたにそれ以上のデータを送るつもりはありません。これはチャネル上のストリームの終わりであり、ピアが接続を閉じたこと、または少なくとも出力のためにシャットダウンしたことを意味します。それを閉じます。 – EJP

+0

ええ、それは本当に私の側でも閉じなければなりません。それは決して私の場合に起こるはずはないが、それは別の話だ。再度、感謝します。 – riha

0

結果の配列の長さは0であり、情報を保持することはできません。バイト配列が大きくならず、バッファの内容を追加できません。 java.io.ByteArrayOutputStreamを使用して結果を累積します。

+0

間違っています。彼の結果配列はループ内で再割り当てされます。 – EJP

+0

'ByteArrayOutputStream'のヒント。それは物事をより簡単にします。 – riha

関連する問題