2014-07-08 2 views
2

다음 테스트 코드가 있습니다. 내가 어떻게 넣을 수 있고, 자바 NIO ByteBuffer를 사용하여 String을 얻을 수 있는지 알고 싶다. 도움이 필요한 곳에 두 가지 의견을 추가했습니다. 그래서Java NIO ByteBuffer : 문자열 넣기 및 가져 오기

You ordered 12 units of ???? 
[...] 

하고 :

package testPipe; 

import java.io.UnsupportedEncodingException; 
import java.nio.ByteBuffer; 
import java.nio.charset.Charset; 
import java.nio.charset.CharsetDecoder; 
import java.nio.charset.CharsetEncoder; 

public class TestMemBuff { 

    static final String dataFile = "invoicedata"; 
    static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 }; 
    static final int[] units = { 12, 8, 13, 29, 50 }; 
    static final String[] descs = { "Java T-shirt", "Java Mug", 
      "Duke Juggling Dolls", "Java Pin", "Java Key Chain" }; 

    public static Charset charset = Charset.forName("UTF-8"); 
    public static CharsetEncoder encoder = charset.newEncoder(); 
    public static CharsetDecoder decoder = charset.newDecoder(); 

    public static void main(String[] args) throws UnsupportedEncodingException { 

     double price; 
     int unit; 
     String desc; 
     double total = 0.0; 

     ByteBuffer buf = ByteBuffer.allocate(1024); 


     for (int i = 0; i < prices.length; i++) { 
      buf.putDouble(prices[i]); 
      buf.putInt(units[i]); 
      buf.asCharBuffer().put(descs[i]);   // Is it correct? 
     } 

     buf.flip(); 

     // INPUT 
     while (buf.hasRemaining()) { 

      price = buf.getDouble(); 
      unit = buf.getInt(); 
      desc = buf.asCharBuffer().toString();  //This must be wrong! 
      System.out.format("You ordered %d" + " units of %s at $%.2f%n", 
        unit, desc, price); 
      total += unit * price; 
     } 
    } 

} 

는 그것을 실행할 출력한다. 관심

+0

실제로'???? '를 인쇄합니까? 'toString'은 무엇을합니까? –

+0

예. 인코딩/디코딩에 문제가있을 것입니다. – user3727540

답변

3

쓰기 부분 :

for (int i = 0; i < prices.length; i++) { 
    buf.putDouble(prices[i]); 
    buf.putInt(units[i]); 

    byte[] descsBytes = descs[i].getBytes(); 
    buf.putInt(descsBytes.length); 
    buf.put(descsBytes); 
} 

읽기 부분 :

while (buf.hasRemaining()) { 

    price = buf.getDouble(); 
    unit = buf.getInt(); 

    int len = buf.getInt(); 
    byte[] bytes = new byte[len]; 
    buf.get(bytes); 
    desc = new String(bytes); 

    System.out.format("You ordered %d" + " units of %s at $%.2f%n", 
       unit, desc, price); 
    total += unit * price; 
} 
+0

그것은 작동합니다! 고마워요! ByteBuffer.asCharBuffer()를 올바르게 사용하는 방법을 알려주시겠습니까? 내 접근 방식에 무슨 문제가 있었습니까? – user3727540

+0

'asCharBuffer'는'ByteBuffer'의 뷰만을 생성합니다.이 뷰의 위치 값은 원래의 버퍼와 독립적입니다. 그래서 2 번째 반복에서 버퍼를 쓰는 동안 문자열 바이트는'double' 값,'int' 등으로 덮어 씌워지고 있습니다 ... ref : http://docs.oracle.com/javase/7/docs /api/java/nio/ByteBuffer.html#asCharBuffer() 여러분이'descs [i]'의 최대 길이를 확신한다면,'byte [] bytes'를 미리 할당하여'new '연산자를 읽습니다. – kujeensiti

+0

시간 내 주셔서 감사합니다. Greeat 대답 :) – user3727540

1

ByteBuffer.asCharBuffer()에 대한

덕분에 어느 정도 자신의 행동이있다. ByteBuffer와 내용을 공유하지만 자체 독립 위치 인 & 제한을 갖는 새 버퍼를 만듭니다. 그래서 CharBuffer에 put() 및 get()을 수행하면 ByteBuffer의 위치가 변경되지 않습니다!

그래서 내가 정확히을 사용하는 것을 삼가고 싶습니다.

그래서 솔루션을 작성하고 원래의 ByteBuffer에 바이트를 읽는 것 :

buf.putInt(descs[i].length); 
buf.put(descs[i].getBytes());` 

문자열을 다시 길이를 읽고 읽고 할당하려면 바이트 [] 자신 :

int stringLength = buf.getInt(); 
byte[] bytes = new byte[stringLength]; 
buf.get(bytes); 
desc = new String(bytes); 
+0

고마워,하지만 난 여전히 오류가 발생합니다 : 당신은 12 단위의 ??? 스레드에서 예외 "주"java.nio.BufferUnderflowException testPipe.TestMemBuff.main에서 java.nio.CharBuffer.get (알 수없는 소스) java.nio.CharBuffer.get에서 \t (알 수없는 소스) \t에서 \t (TestMemBuff.java:48) – user3727540