Java - ByteBuffer.remaining() 问题

Posted

技术标签:

【中文标题】Java - ByteBuffer.remaining() 问题【英文标题】:Java - ByteBuffer.remaining() problems 【发布时间】:2009-11-15 03:59:35 【问题描述】:

总结:我有一个 ByteBuffer,我在其中抽取一些数据。之后,我想通过 Socket 发送这些数据。

所以,我写了这样的代码:

    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());

在调用代码中,我执行以下操作。我先得到序列化的 ByteBuffer,然后把它写到 socket...

            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;
        

我期望 buffer.remaining() 应该完全等于我泵入缓冲区的#bytes。但是我发现它不是,它总是等于 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 in output buffer: 1024 限制 = 1024 pos = 0 剩余 = 1024

我怎样才能获得放入缓冲区的确切#bytes?

谢谢!

【问题讨论】:

【参考方案1】:

当您完成将字节放入缓冲区后,您应该flip 它。您可以这样做来代替第一次致电 rewind

java.nio.Buffer 区分 capacitylimit。如果你不翻转它,那么limit和容量就是你初始化它的数组的长度。

通过翻转它,限制将设置为您编码的数据的末尾,容量仍为 1024。ByteBuffer#remaining 查看位置和限制之间的增量。

【讨论】:

以上是关于Java - ByteBuffer.remaining() 问题的主要内容,如果未能解决你的问题,请参考以下文章

Java 布尔运算

java [Java] Java常用代码#java

Java - 35 Java 实例

Java While 循环

Java 字符串

Java If ... Else