2012-03-22 3 views
0

저는 SocketChannel에서 BLOCKSIZE (예 : 512) 바이트의 블록을 ByteBuffer로 연속해서 읽습니다. ByteBuffer 내용을 바이트 []에 추가하고 다음 라운드로 이동하려고합니다. 결과는 SocketChannel에서 읽은 모든 바이트를 포함하는 byte []가됩니다.ByteBuffer에서 byte []에 도달하면 byte []에 쓰지 않습니다.

이제 System.arraycopy (...)가 예상대로 작동합니다. 그러나 ByteBuffer의 get (result, offset, length)을 사용하면 아무 것도 쓰이지 않습니다. 결과 배열 값은 0으로 유지됩니다.

왜 그럴까요?

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

편집 :

나는 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

'flip()'이 (가) 트릭을했습니다. 감사합니다. 나는'compact()'가 필요 없다고 생각한다. 버퍼로부터 모든 것을'get()'한 후에, 아무 것도 압축되지 않으며 어쨌든 각 반복마다'clear()'됩니다. 또한 채널 폐쇄에 대한 힌트를 주셔서 감사합니다. 나는 채널이 열려 있고 그것이 의도 된 것이라는 것을 알고 있습니다. 클라이언트는 언제든지 새로운 데이터를 전송할 수 있습니다. – riha

+0

@riha 틀렸어. -1을 얻은 후에는 클라이언트가 더 이상 데이터를 보내지 않습니다. 채널의 스트림 끝입니다. 피어가 연결을 종료했거나 적어도 출력을 위해 종료했음을 의미합니다. 닫아. – EJP

+0

흠 좋아, 그럼 정말 내 편이 닫혀 야해. 그것은 내 경우에는 결코 일어나지 않을 것이지만, 그것은 또 다른 이야기입니다. 다시 한번 감사드립니다. – riha

0

결과 배열의 길이는 0이며 정보를 보유 할 수 없습니다. 바이트 배열이 커지지 않으며 버퍼의 내용을 추가 할 수 없습니다. 결과를 누적하려면 java.io.ByteArrayOutputStream을 사용하십시오.

+0

잘못되었습니다. 그의 결과 배열은 루프 내부에서 재 할당됩니다. – EJP

+0

ByteArrayOutputStream에 좋은 힌트가 있습니다. 그것은 물건을 더 단순하게 만든다. – riha

관련 문제