何时使用字节数组和什么时候字节缓冲区?
字节数组和字节数组有什么区别?字节缓冲区?
此外,在什么情况下应该优先选择其中一种?
[我的用例是用 java 开发的 Web 应用程序]。
What is the difference between a byte array & byte buffer ?
Also, in what situations should one be preferred over the other?
[my usecase is for a web application being developed in java].
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
实际上有多种处理字节的方法。我同意,选择最好的一个并不总是那么容易:
byte[]
java.nio.ByteBuffer
java.io.ByteArrayOutputStream
> (与其他流结合)java.util.BitSet
byte[]
只是一个原始数组,仅包含原始数据。因此,它没有方便的方法来构建或操作内容。ByteBuffer
更像是一个构建器。它创建一个byte[]
。与数组不同,它有更方便的辅助方法。 (例如append(byte)
方法)。就用法而言,并不是那么简单。 (大多数教程都太复杂或质量很差,但是这个一个 会让你更进一步吗?然后阅读许多陷阱。)你可能会想说
ByteBuffer
对byte[]
起作用,StringBuilder
对String
做什么。但是 ByteBuffer 类有一个特定的区别/缺点。尽管看起来字节缓冲区在您添加元素时会自动调整大小,但ByteBuffer
实际上具有固定容量。当您实例化它时,您必须指定缓冲区的最大大小。这就是为什么我经常更喜欢使用
ByteArrayOutputStream
的原因之一,因为它会自动调整大小,就像ArrayList
一样。 (它有一个 toByteArray() 方法)。有时将其包装在DataOutputStream
中是很实用的。优点是您将有一些额外的方便调用,(例如writeShort(int)
如果您需要写入 2 个字节。)BitSet
当您想要执行位级操作时会派上用场。您可以获取/设置单个位,并且它有逻辑运算符像xor()
这样的方法。 (toByteArray()
方法仅在 java 7 中引入。)当然,根据您的需要,您可以将所有这些组合起来构建您的
byte[]
。There are actually a number of ways to work with bytes. And I agree that it's not always easy to pick the best one:
byte[]
java.nio.ByteBuffer
java.io.ByteArrayOutputStream
(in combination with other streams)java.util.BitSet
The
byte[]
is just a primitive array, just containing the raw data. So, it does not have convenient methods for building or manipulating the content.A
ByteBuffer
is more like a builder. It creates abyte[]
. Unlike arrays, it has more convenient helper methods. (e.g. theappend(byte)
method). It's not that straightforward in terms of usage. (Most tutorials are way too complicated or of poor quality, but this one will get you somewhere. Take it one step further? then read about the many pitfalls.)You could be tempted to say that a
ByteBuffer
does tobyte[]
, what aStringBuilder
does forString
. But there is a specific difference/shortcoming of theByteBuffer
class. Although it may appear that a bytebuffer resizes automatically while you add elements, theByteBuffer
actually has a fixed capacity. When you instantiate it, you already have to specify the maximum size of the buffer.That's one of the reasons, why I often prefer to use the
ByteArrayOutputStream
because it automatically resizes, just like anArrayList
does. (It has atoByteArray()
method). Sometimes it's practical, to wrap it in aDataOutputStream
. The advantage is that you will have some additional convenience calls, (e.g.writeShort(int)
if you need to write 2 bytes.)BitSet
comes in handy when you want to perform bit-level operations. You can get/set individual bits, and it has logical operator methods likexor()
. (ThetoByteArray()
method was only introduced in java 7.)Of course depending on your needs you can combine all of them to build your
byte[]
.ByteBuffer 是新 IO 包 (nio) 的一部分,该包是为基于文件的数据的快速吞吐量而开发的。具体来说,Apache 是一个非常快的 Web 服务器(用 C 语言编写),因为它从磁盘读取字节并将它们直接放到网络上,而不需要通过各种缓冲区对它们进行混洗。它通过内存映射文件来实现这一点,而早期版本的 Java 没有这种文件。随着 nio 的出现,用 java 编写一个与 Apache 一样快的 Web 服务器成为可能。当您想要非常快的文件到网络吞吐量时,您需要使用内存映射文件和 ByteBuffer。
数据库通常使用内存映射文件,但这种类型的使用在 Java 中效率很低。在 C/C++ 中,可以加载大块内存并将其转换为您想要的类型化数据。由于 Java 的安全模型,这通常是不可行的,因为您只能转换为某些本机类型,并且这些转换效率不高。当您仅将字节作为纯字节数据处理时,ByteBuffer 效果最佳 - 一旦您需要将它们转换为对象,其他 java io 类通常会表现更好并且更易于使用。
如果您不处理内存映射文件,那么您实际上不需要担心 ByteBuffer ——您通常会使用字节数组。如果您正在尝试构建一个 Web 服务器,并以最快的速度处理基于文件的原始字节数据,那么 ByteBuffer(特别是 MappedByteBuffer)是您最好的朋友。
ByteBuffer is part of the new IO package (nio) that was developed for fast throughput of file-based data. Specifically, Apache is a very fast web server (written in C) because it reads bytes from disk and puts them on the network directly, without shuffling them through various buffers. It does this through memory-mapped files, which early versions of Java did not have. With the advent of nio, it became possible to write a web server in java that is as fast as Apache. When you want very fast file-to-network throughput, then you want to use memory mapped files and ByteBuffer.
Databases typically use memory-mapped files, but this type of usage is seldom efficient in Java. In C/C++, it's possible to load up a large chunk of memory and cast it to the typed data you want. Due to Java's security model, this isn't generally feasible, because you can only convert to certain native types, and these conversions aren't very efficient. ByteBuffer works best when you are just dealing with bytes as plain byte data -- once you need to convert them to objects, the other java io classes typically perform better and are easier to use.
If you're not dealing with memory mapped files, then you don't really need to bother with ByteBuffer -- you'd normally use arrays of byte. If you're trying to build a web server, with the fastest possible throughput of file-based raw byte data, then ByteBuffer (specifically MappedByteBuffer) is your best friend.
这两篇文章可能会帮助您http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly 和 http://evanjones.ca/software/java-bytebuffers.html
Those two articles may help you http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly and http://evanjones.ca/software/java-bytebuffers.html