成长ByteBuffer

Set*_*eth 40 java bytebuffer

有没有人见过java.nio.ByteBuffer的实现,如果putX()调用超出容量,它将动态增长?

我想这样做的原因有两个:

  1. 我不知道我需要多少空间.
  2. 每次空间不足时,我宁愿不再使用新的ByteBuffer.allocate(),而是使用批量put().

bri*_*gge 36

为了使异步I/O工作,您必须具有连续的内存.在C中,您可以尝试重新分配数组,但在Java中,您必须分配新内存.您可以写入a ByteArrayOutputStream,然后ByteBuffer在准备发送它时将其转换为a .缺点是您正在复制内存,高效IO的关键之一是减少内存复制的次数.

  • ByteArrayOutputStream 实际上正是我想要的(我实际上没有做任何 I/O,我只是有一些复杂的序列化要做)。谢谢! (2认同)
  • Seth,你的问题陈述("putX")暗示你需要像putInt,putDouble等方法,这暗示ByteArrayOutputStream对你来说是不够的,因此我回答了ByteArrayDataOutput. (2认同)

Kev*_*ion 10

ByteBuffer不能真正以这种方式工作,因为它的设计概念只是一个特定数组的视图,您也可以直接引用它.它不能尝试将该数组交换为更大的数组,而不会发生奇怪的事情.

你想要用的是一个DataOutput.最方便的方法是使用(预发布)Guava库:

ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.write(someBytes);
out.writeInt(someInt);
// ...
return out.toByteArray();
Run Code Online (Sandbox Code Playgroud)

但您也可以手动从ByteArrayOutputStream创建DataOutputStream,并通过将它们链接到AssertionErrors来处理虚假的IOExceptions.

  • @EJP 这些是 Kevin 提到的来自 [Google Guava](https://code.google.com/p/guava-libraries/) 的课程。 (2认同)

Pet*_*rey 6

看看Mina IOBuffer https://mina.apache.org/mina-project/userguide/ch8-iobuffer/ch8-iobuffer.html这是一个替代品(它包装了ByteBuffer)

但是,我建议你分配超过你需要的东西,不要太担心它.如果你分配一个缓冲区(特别是一个直接缓冲区),操作系统会为它提供虚拟内存,但它只在实际使用时才使用物理内存.虚拟内存应该非常便宜.

  • 我喜欢页面上的警告:"MINA在nio ByteBuffer上有自己的包装器的主要原因是有可扩展的缓冲区.这是一个非常糟糕的决定." (6认同)

ano*_*ous 5

看看 Netty 的DynamicChannelBuffer也可能是值得的。我觉得方便的事情是:

  • slice(int index, int length)
  • 无符号操作
  • 分离的作者和读者索引


Pet*_*rey 5

另一种选择是使用具有大缓冲区的直接内存.这会消耗虚拟内存,但只使用你使用的物理内存(按页面通常为4K)

因此,如果您分配1 MB的缓冲区,它会占用1 MB的虚拟内存,但唯一的操作系统会为实际使用的应用程序提供物理页面.

效果是你看到你的应用程序使用了大量的虚拟内存,但是相对少量的驻留内存.