Growing ByteBuffer

前端 未结 11 1089
温柔的废话
温柔的废话 2021-01-31 14:21

Has anyone has ever seen an implementation of java.nio.ByteBuffer that will grow dynamically if a putX() call overruns the capacity?

The reason I want to do it this way

相关标签:
11条回答
  • 2021-01-31 15:07

    Another solution for this would be to allocate more than enough memory, fill the ByteBuffer and then only return the occupied byte array:

    Initialize a big ByteBuffer:

    ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
    

    After you're done putting things into it:

    private static byte[] getOccupiedArray(ByteBuffer byteBuffer)
    {
        int position = byteBuffer.position();
        return Arrays.copyOfRange(byteBuffer.array(), 0, position);
    }
    

    However, using a org.apache.commons.io.output.ByteArrayOutputStream from the start would probably be the best solution.

    0 讨论(0)
  • 2021-01-31 15:10

    Indeed, auto-extending buffers are so much more intuitive to work with. If you can afford the performance luxury of reallocation, why wouldn't you!?

    Netty's ByteBuf gives you exactly this. It's like they've taken java.nio's ByteBuffer and scraped away the edges, making it much easier to use.

    Furthermore, it's on Maven in an independent netty-buffer package so you don't need to include the full Netty suite to use.

    0 讨论(0)
  • 2021-01-31 15:11

    A ByteBuffer cannot really work this way, as its design concept is to be just a view of a specific array, which you may also have a direct reference to. It could not try to swap that array for a larger array without weirdness happening.

    What you want to use is a DataOutput. The most convenient way is to use the (pre-release) Guava library:

    ByteArrayDataOutput out = ByteStreams.newDataOutput();
    out.write(someBytes);
    out.writeInt(someInt);
    // ...
    return out.toByteArray();
    

    But you could also create a DataOutputStream from a ByteArrayOutputStream manually, and just deal with the spurious IOExceptions by chaining them into AssertionErrors.

    0 讨论(0)
  • 2021-01-31 15:13

    Have a look at Mina IOBuffer https://mina.apache.org/mina-project/userguide/ch8-iobuffer/ch8-iobuffer.html which is a drop in replacement (it wraps the ByteBuffer)

    However , I suggest you allocate more than you need and don't worry about it too much. If you allocate a buffer (esp a direct buffer) the OS gives it virtual memory but it only uses physical memory when its actually used. Virtual memory should be very cheap.

    0 讨论(0)
  • 2021-01-31 15:19

    Another option is to use direct memory with a large buffer. This consumes virtual memory but only uses as much physical memory as you use (by page which is typically 4K)

    So if you allocate a buffer of 1 MB, it comsumes 1 MB of virtual memory, but the only OS gives physical pages to the application which is actually uses.

    The effect is you see your application using alot of virtual memory but a relatively small amount of resident memory.

    0 讨论(0)
提交回复
热议问题