最近我创建了一个包装器来读取和写入byte
数组中的数据。要做到这一点,我一直在使用ArrayList<Byte>
,但我想知道这是否是最有效的方法,因为:
addAll()
无法使用byte
数组(即使使用Arrays.asList()
,也会返回List<Byte[]>
)。为了解决这个问题,我只是在每个循环中循环并添加byte
,但我想这会假设很多函数调用,因此它具有性能成本。byte[]
获取ArrayList
也是如此。我无法从Byte[]
投射到byte[]
,所以我必须使用循环。我知道ByteArrayInputStream
和ByteArrayOutputStream
可以用于此,但它有一些不便之处:
readInt
,readLEInt
,readUInt
等),而这些类只能读/写一个字节或一个字节数组。这不是一个真正的问题,因为我可以在包装器中解决这个问题。但这是第二个问题。ByteArrayInputStream
和ByteArrayOutputStream
。我不知道那些是否可以以某种方式同步,或者每次我写信给包装器时我都必须将一个数据写入另一个。所以,我的问题就出现了:使用ByteBuffer
会更有效吗?我知道您可以从中获取integers
,floats
等,甚至可以更改字节顺序。我想知道的是,使用ByteBuffer
和ArrayList<Byte>
之间是否存在真正的性能变化。
答案 0 :(得分:3)
绝对 ByteBuffer 或 ByteArrayOutputStream 。在你的情况下,ByteBuffer似乎很好。 检查Javadoc,因为它有很好的方法,对于putInt / getInt等,你可能想设置顺序(那4个字节)
byteBuffer.order(ByteBuffer.LITTLE_ENDIAN);
使用文件,您可以使用getChannel()
或变体,然后使用MappedByteBuffer
。
ByteBuffer可以包装一个字节数组,或者分配。
答案 1 :(得分:1)
请记住,每个对象都有与之相关的开销,包括每个对象的一些内存和一旦超出范围的垃圾回收。
使用List<Byte>
意味着每个字节创建/垃圾收集一个对象非常浪费。
答案 2 :(得分:0)
ByteBuffer是一个围绕字节数组的包装类,它不像ArrayList那样具有动态大小,但它每字节消耗的内存更少,速度更快。 如果你知道你需要的大小,那么使用ByteBuffer,如果你没有,那么你可以使用ByteArrayOutputStream(也许可以用ObjectOutputStream包装,它有一些方法来编写不同类型的数据)。要读取你写入ByteArrayOutputStream的数据,你可以扩展ByteArrayOutputStream,然后你可以访问字段buf []和count,这些字段是受保护的,所以你可以从扩展类访问它们,它看起来像:
public class ByteArrayOutputStream extends OutputStream {
/**
* The buffer where data is stored.
*/
protected byte buf[];
/**
* The number of valid bytes in the buffer.
*/
protected int count;
...
}
public class ReadableBAOS extends ByteArrayOutputStream{
public byte readByte(int index) {
if (count>index) {
throw new IndexOutOfBoundsException();
}
return buf[index];
}
}
所以你可以在扩展类中创建一些方法来从底层缓冲区读取一些字节,而不需要每次像toByteArray()方法那样复制它的内容。