简体   繁体   English

Java - ByteBuffer.remaining()问题

[英]Java - ByteBuffer.remaining() problems

Summary: I have a ByteBuffer in which I am pumping some data. 简介:我有一个ByteBuffer,我在其中提取一些数据。 After that, I want to send this data over a Socket. 之后,我想通过Socket发送这些数据。

So, I wrote code like this: 所以,我写了这样的代码:

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

In the calling code, I do the following. 在调用代码中,我执行以下操作。 I first get the serialized ByteBuffer and then write it out to the socket... 我首先得到序列化的ByteBuffer,然后将其写入套接字......

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

I am expecting that buffer.remaining() should be exactly equal to the #bytes I pumped into the buffer. 我期望buffer.remaining()应该完全等于我输入缓冲区的#bytes。 However I am finding that it is not, it is always equal to 1024, which is the size of the underlying array of the buffer. 但是我发现它不是,它总是等于1024,这是缓冲区底层数组的大小。

This is how I create the buffer... 这就是我创建缓冲区的方法......

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

This is what I get as the output of my print statement... 这就是我得到的print语句输出...

String [John] #bytes = 4 String [Smith] #bytes = 5 String [John] #bytes = 4 String [Smith] #bytes = 5

#Bytes in output buffer: 1024 limit = 1024 pos = 0 remaining = 1024 输出缓冲区中的#Bytes:1024 limit = 1024 pos = 0 remaining = 1024

How can I get the exact #bytes that were put into the buffer? 如何获得放入缓冲区的确切#bytes?

Thanks! 谢谢!

When you are done putting bytes into the buffer, you should flip it. 当你完成将字节放入缓冲区时,你应该flip它。 You can probably do this in place of your first call to rewind instead. 你也许可以做到这一点的地方你的第一个电话来rewind代替。

A java.nio.Buffer distinguishes between capacity and limit . java.nio.Buffer区分capacitylimit If you don't flip it, then limit and capacity are the same as the length of the array with which you initialized it. 如果不翻转它,则limit和capacity与初始化它的数组的长度相同。

By flipping it, the limit will be set to the end of the data you've encoded, and capacity will still be 1024. ByteBuffer#remaining looks at the delta between position and limit. 通过翻转它,限制将设置为您编码的数据的末尾,容量仍然是1024. ByteBuffer#remaining查看位置和限制之间的差值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM