有没有人见过一个可以动态增长的 java.nio.ByteBuffer 实现,当 putX() 调用超出容量时会增长?
我希望这样做有两个原因:
- 我不知道需要多少空间。
- 我不想每次空间不足时都要执行 new ByteBuffer.allocate() 然后进行批量 put()。
有没有人见过一个可以动态增长的 java.nio.ByteBuffer 实现,当 putX() 调用超出容量时会增长?
我希望这样做有两个原因:
ByteBuffer不能以这种方式工作,因为它的设计理念是仅作为特定数组的视图,您也可以直接引用该数组。如果尝试将该数组替换为更大的数组,则会发生奇怪的问题。
您需要使用的是。最方便的方法是使用(预发行版)Guava库:
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.write(someBytes);
out.writeInt(someInt);
// ...
return out.toByteArray();
你还可以手动从ByteArrayOutputStream创建DataOutputStream,然后通过将它们链接为AssertionErrors处理假的IOExceptions。
ByteArrayDataOutput
和ByteStreams
。你指的是什么? - user207421new DataOutputStream(new ByteArrayOutputStream())
。 - user207421DataOutput
,然后给出了两个例子。一个使用Guava,另一个与您在评论中提到的完全相同。ByteArrayDataOutput
和DataOutputStream
都实现了该接口。 - agermano另一种选择是使用具有大缓冲区的直接内存。这会消耗虚拟内存,但只使用您实际使用的物理内存(按页面计算,通常为4K)
因此,如果您分配了1 MB的缓冲区,则会消耗1 MB的虚拟内存,但操作系统只会将物理页面提供给应用程序实际使用的部分。
效果是您会看到应用程序使用大量虚拟内存,但占用的驻留内存相对较小。
也许值得看一下Netty的DynamicChannelBuffer。我发现以下内容很方便:
slice(int index, int length)
的确,自动扩展缓冲区更符合直觉。如果您能够承担性能上的损失,为什么不这么做呢?
ByteBuf
是 Netty 提供的一种缓冲区实现,它就像是对 java.nio
的 ByteBuffer
进行了裁剪,让它更易于使用。
此外,独立的 netty-buffer
包也已经在 Maven 上发布,因此您不需要引入完整的 Netty 套件即可使用。
我建议使用输入流从文件中接收数据(如果需要非阻塞,则使用单独的线程),然后将字节读入ByteArrayOutputStream中,这样可以将其作为字节数组获取。下面是一个简单的示例,没有添加太多的解决方法。
try (InputStream inputStream = Files.newInputStream(
Paths.get("filepath"), StandardOpenOption.READ)){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int byteRead = 0;
while(byteRead != -1){
byteRead = inputStream.read();
baos.write(byteRead);
}
ByteBuffer byteBuffer = ByteBuffer.allocate(baos.size())
byteBuffer.put(baos.toByteArray());
//. . . . use the buffer however you want
}catch(InvalidPathException pathException){
System.out.println("Path exception: " + pathException);
}
catch (IOException exception){
System.out.println("I/O exception: " + exception);
}
ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
private static byte[] getOccupiedArray(ByteBuffer byteBuffer)
{
int position = byteBuffer.position();
return Arrays.copyOfRange(byteBuffer.array(), 0, position);
}
org.apache.commons.io.output.ByteArrayOutputStream
可能是最好的解决方案。Netty的ByteBuf在这方面非常好。
Vector 允许不断增长
Vector<Byte> bFOO = new Vector<Byte>();
bFOO.add((byte) 0x00);
ArrayList
与数组的权衡差不多。就像使用ArrayList
一样,您可以使用初始容量(构造函数ByteArrayOutputStream(int capacity)
)进行实例化。例如,如果您希望有大约800个字节的数据,则可以使用类似于new ByteArrayOutputStream(1024)
的内容。这将防止(或��少)调整大小的次数。 - bvdb