【发布时间】:2011-07-09 19:28:12
【问题描述】:
字节数组和字节缓冲区有什么区别?
另外,在什么情况下应该优先考虑一个?
[我的用例是用 java 开发的 Web 应用程序]。
【问题讨论】:
标签: java byte bytearray buffer
字节数组和字节缓冲区有什么区别?
另外,在什么情况下应该优先考虑一个?
[我的用例是用 java 开发的 Web 应用程序]。
【问题讨论】:
标签: java byte bytearray buffer
实际上有很多方法可以处理字节。而且我同意选择最好的并不总是那么容易:
byte[]
java.nio.ByteBuffer
java.io.ByteArrayOutputStream(与其他流结合使用)java.util.BitSet
byte[] 只是一个原始数组,仅包含原始数据。因此,它没有方便的方法来构建或操作内容。
ByteBuffer 更像是一个构建器。它创建了一个byte[]。与数组不同,它有更方便的辅助方法。 (例如append(byte) 方法)。就usage 而言,这并不是那么简单。 (大多数教程太复杂或质量很差,但这个one 会让你有所收获。更进一步?然后阅读更多pitfalls。)
您可能会想说ByteBuffer 对byte[] 的作用,StringBuilder 对String 的作用。但是ByteBuffer 类有一个特定的区别/缺点。虽然看起来字节缓冲区在您添加元素时会自动调整大小,但ByteBuffer 实际上具有固定容量。当您实例化它时,您已经必须指定最大大小 缓冲区。
这就是为什么我经常喜欢使用ByteArrayOutputStream 的原因之一,因为它会自动调整大小,就像ArrayList 一样。 (它有一个toByteArray() 方法)。有时将其包装在DataOutputStream 中很实用。优点是您将有一些额外的方便调用(例如,writeShort(int),如果您需要写入 2 个字节。)
BitSet 在您想要执行位级操作时会派上用场。 您可以获取/设置单个位,它具有像 xor() 这样的逻辑运算符方法。 (toByteArray() 方法仅在 java 7 中引入。)
当然,根据您的需要,您可以将所有这些组合起来构建您的byte[]。
【讨论】:
ByteBuffer 是新 IO 包 (nio) 的一部分,该包是为快速处理基于文件的数据而开发的。具体来说,Apache 是一个非常快速的 Web 服务器(用 C 语言编写),因为它从磁盘读取字节并将它们直接放到网络上,而无需通过各种缓冲区对它们进行混洗。它通过内存映射文件来做到这一点,而早期版本的 Java 没有。随着 nio 的出现,用 Java 编写与 Apache 一样快的 Web 服务器成为可能。当您想要非常快的文件到网络吞吐量时,您需要使用内存映射文件和 ByteBuffer。
数据库通常使用内存映射文件,但这种用法在 Java 中很少有效率。在 C/C++ 中,可以加载大量内存并将其转换为所需的类型数据。由于 Java 的安全模型,这通常是不可行的,因为您只能转换为某些本机类型,而这些转换效率不高。当您仅将字节作为纯字节数据处理时,ByteBuffer 效果最好——一旦您需要将它们转换为对象,其他 java io 类通常性能更好并且更易于使用。
如果您不处理内存映射文件,那么您实际上不需要为 ByteBuffer 操心——您通常会使用字节数组。如果您正在尝试构建一个 Web 服务器,以尽可能快地处理基于文件的原始字节数据,那么 ByteBuffer(特别是 MappedByteBuffer)是您最好的朋友。
【讨论】:
Unsafe。
【讨论】: