2009-11-15 1 views
3

요약 : 일부 데이터를 펌핑하는 ByteBuffer가 있습니다. 그 후 소켓을 통해이 데이터를 보내려고합니다.Java - ByteBuffer.remaining() problems

그래서, 같은 코드 작성 : 호출 코드에서

private static void serialize(ByteBuffer buffer, EmployeeData emp, CharsetEncoder encoder) 
{ 
    // id 
    buffer.putInt(emp.getId()); 

    CharBuffer nameBuffer = CharBuffer.wrap(emp.getFirstName().toCharArray()); 
    ByteBuffer nbBuffer = null; 

    // length of first name 
    try 
    { 
     nbBuffer = encoder.encode(nameBuffer); 
    } 
    catch(CharacterCodingException e) 
    { 
     throw new ArithmeticException(); 
    } 

    System.out.println(String.format("String [%1$s] #bytes = %2$s", emp.getFirstName(), nbBuffer.limit())); 
    buffer.putInt(nbBuffer.limit()); 
    buffer.put(nbBuffer); 

    // put lastname 
    nameBuffer = CharBuffer.wrap(emp.getLastName().toCharArray()); 
    nbBuffer = null; 

    // length of first name 
    try 
    { 
     nbBuffer = encoder.encode(nameBuffer);   
    } 
    catch(CharacterCodingException e) 
    { 
     throw new ArithmeticException(); 
    } 

    System.out.println(String.format("String [%1$s] #bytes = %2$s", emp.getLastName(), nbBuffer.limit())); 
    buffer.putInt(nbBuffer.limit()); 
    buffer.put(nbBuffer); 

    // salary 
    buffer.putInt(emp.getSalary()); 
} 

을, 나는 다음을 수행합니다. 내가 버퍼에 펌핑 #bytes 정확하게 일치해야한다는 buffer.remaining()를 기대하고

  Socket client = new Socket("localhost", 8080); 

     OutputStream oStream = client.getOutputStream(); 

     serialize(buffer, emp, encoder); 

     buffer.rewind();    
     while(buffer.hasRemaining()) 
     { 
      byte temp = buffer.get(); 
      ++ written; 
     } 

     buffer.rewind(); 
     System.out.println("#Bytes in output buffer: " + written + " limit = " + buffer.limit() + " pos = " + buffer.position() + " remaining = " + buffer.remaining()); 

     int remaining = buffer.remaining(); 
     while(remaining > 0) 
     { 
      oStream.write(buffer.get()); 
      -- remaining; 
     } 

내가 먼저 ... 직렬화의 ByteBuffer를 얻을 후 소켓에 쓰는. 그러나 나는 그렇지 않다는 것을 알았습니다. 항상 버퍼의 기본 배열 크기 인 1024와 같습니다.

 Charset charset = Charset.forName("UTF-8"); 
    CharsetDecoder decoder = charset.newDecoder(); 
    CharsetEncoder encoder = charset.newEncoder(); 
    byte [] underlyingBuffer = new byte[1024]; 
    ByteBuffer buffer = ByteBuffer.wrap(underlyingBuffer); 
    buffer.order(ByteOrder.LITTLE_ENDIAN); 

내가 내 인쇄 문의 출력으로 무엇을 얻을 나는 버퍼를 생성하는 방법이있다

...

문자열 [존] #bytes = 4 문자열 [스미스] #bytes = 5

#Bytes 출력 버퍼 : 1024 한계 = 1,024 POS = 0 나머지 = 1,024

버퍼에 넣은 정확한 #bytes는 어떻게 얻을 수 있습니까?

감사합니다.

답변

11

바이트를 버퍼에 넣었 으면 flip입니다. 대신 rewind으로 첫 번째 전화 대신이 작업을 수행 할 수 있습니다.

java.nio.Buffercapacitylimit을 구별합니다. 뒤집지 않으면 제한 및 용량이 초기화 된 배열의 길이와 같습니다.

코드를 뒤집으면 인코딩 한 데이터의 끝으로 제한이 설정되고 용량은 여전히 ​​1024가됩니다. ByteBuffer#remaining은 위치와 한도 사이의 델타를 봅니다.

+0

감사합니다. Joe. 그것은 그것을 고쳤다. – feroze