何时使用字节数组和何时字节缓冲区?

字节数组和字节缓冲区有什么区别?
另外,在什么情况下应该比另一个更受欢迎?

[我的用例是用于在Java中开发的Web应用程序]。

ByteBuffer是新的IO包(nio)的一部分,它是为基于文件的数据的快速吞吐量而开发的。 具体而言,Apache是​​一个非常快速的Web服务器(用C语言编写),因为它从磁盘读取字节,并直接将它们放在networking上,而不用通过各种缓冲区来移动它们。 它通过内存映射文件来完成,Java的早期版本没有。 随着nio的出现,可以用Java编写一个和Apache一样快的Web服务器。 当你想要非常快的文件到networking的吞吐量,那么你想使用内存映射文件和ByteBuffer。

数据库通常使用内存映射文件,但在Java中这种用法很less有效。 在C / C ++中,可以加载大量内存并将其转换为所需的types化数据。 由于Java的安全模型,这通常是不可行的,因为只能转换为某些本地types,而这些转换效率不高。 ByteBuffer在你只是将字节作为普通字节数据处理时效果最好 – 一旦你需要将它们转换为对象,其他的java io类通常执行得更好并且更容易使用。

如果你不处理内存映射文件,那么你并不需要打扰ByteBuffer–通常你会使用字节数组。 如果您正尝试构build一个Web服务器,并以最快的文件为基础的原始字节数据的吞吐量,那么ByteBuffer(特别是MappedByteBuffer)就是您最好的朋友。

实际上有很多方法来处理字节。 我同意挑选最好的一个并不容易:

  • byte[]
  • java.nio.ByteBuffer
  • java.io.ByteArrayOutputStream (与其他stream组合)
  • java.util.BitSet

byte[]只是一个原始数组,只包含原始数据。 所以,它没有方便的方法来构build或操作内容。

ByteBuffer更像一个build造者。 它用来创build一个byte[] 。 与数组不同,它有更方便的辅助方法。 (例如append(byte)方法)。

你可能会说, ByteBufferbyte[]是这样做的, StringBuilder是为String 。 但是ByteBuffer类有一个特定的区别/缺点。 就像数组一样, ByteBuffer具有固定的大小。 所以,当你实例化它时,你必须指定缓冲区的大小。

这就是为什么我经常更喜欢使用ByteArrayOutputStream的原因之一, 因为它会ArrayList一样自动resize 。 (它有一个toByteArray()方法)。 有时它是实用的,把它包装在一个DataOutputStream 好处是你会有一些额外的方便调用(如writeShort(int)如果你需要写2个字节)。

当您想执行位级操作时, BitSet会派上用场。 您可以获取/设置个别位,并且具有像xor()这样的逻辑运算符方法。 ( toByteArray()方法仅在java 7中引入)

当然,根据您的需要,您可以将它们全部组合起来构build您的byte[]