简体   繁体   English

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

[英]When to use byte array & when byte buffer?

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]. [我的用例是用于在java中开发的Web应用程序]。

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: 我同意选择最好的一个并不总是那么容易:

  • the byte[] byte[]
  • the java.nio.ByteBuffer java.nio.ByteBuffer
  • the java.io.ByteArrayOutputStream (in combination with other streams) java.io.ByteArrayOutputStream (与其他流组合)
  • the java.util.BitSet java.util.BitSet

The byte[] is just a primitive array, just containing the raw data. byte[]只是一个原始数组,只包含原始数据。 So, it does not have convenient methods for building or manipulating the content. 因此,它没有方便的方法来构建或操作内容。

A ByteBuffer is more like a builder. ByteBuffer更像是一个建设者。 It creates a byte[] . 它创建一个byte[] Unlike arrays, it has more convenient helper methods. 与数组不同,它有更方便的辅助方法。 (eg the append(byte) method). (例如append(byte)方法)。 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 to byte[] , what a StringBuilder does for String . 你可能很想说ByteBufferbyte[]做了什么, StringBuilderString做了什么。 But there is a specific difference/shortcoming of the ByteBuffer class. 但是ByteBuffer类有一个特定的差异/缺点。 Just like with arrays, the ByteBuffer has a fixed size. 就像数组一样, ByteBuffer具有固定的大小。 So, when you instantiate it, you already have to specify the size of the buffer. 因此,在实例化它时,您必须指定缓冲区的大小。

That's one of the reasons, why I often prefer to use the ByteArrayOutputStream because it automatically resizes, just like an ArrayList does. 这就是原因之一,为什么我经常更喜欢使用ByteArrayOutputStream因为它会ArrayList一样自动调整大小 (It has a toByteArray() method). (它有一个toByteArray()方法)。 Sometimes it's practical, to wrap it in a DataOutputStream . 有时将它包装在DataOutputStream是实用的。 The advantage is that you will have some additional convenience calls, (eg writeShort(int) if you need to write 2 bytes.) 优点是你将有一些额外的便利调用,(例如,如果需要写2个字节,则为writeShort(int) 。)

BitSet comes in handy when you want to perform bit-level operations. 当您想要执行位级操作时, BitSet会派上用场。 You can get/set individual bits, and it has logical operator methods like xor() . 您可以获取/设置单个位,它具有逻辑运算符方法,如xor() (The toByteArray() method was only introduced in java 7.) toByteArray()方法仅在java 7中引入。)

Of course depending on your needs you can combine all of them to build your byte[] . 当然,根据您的需要,您可以将所有这些组合起来构建您的byte[]

ByteBuffer is part of the new IO package (nio) that was developed for fast throughput of file-based data. ByteBuffer是为基于文件的数据的快速吞吐量而开发的新IO包(nio)的一部分。 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. 具体来说,Apache是​​一个非常快速的Web服务器(用C语言编写),因为它从磁盘读取字节并直接将它们放在网络上,而不需要通过各种缓冲区进行混洗。 It does this through memory-mapped files, which early versions of Java did not have. 它通过内存映射文件实现这一点,而早期版本的Java没有这些文件。 With the advent of nio, it became possible to write a web server in java that is as fast as Apache. 随着nio的出现,可以在Java中编写一个与Apache一样快的Web服务器。 When you want very fast file-to-network throughput, then you want to use memory mapped files and ByteBuffer. 当您需要非常快的文件到网络吞吐量时,则需要使用内存映射文件和ByteBuffer。

Databases typically use memory-mapped files, but this type of usage is seldom efficient in Java. 数据库通常使用内存映射文件,但这种用法在Java中很少有效。 In C/C++, it's possible to load up a large chunk of memory and cast it to the typed data you want. 在C / C ++中,可以加载大量内存并将其转换为您想要的类型化数据。 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. 由于Java的安全模型,这通常不可行,因为您只能转换为某些本机类型,并且这些转换效率不高。 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. 当您将字节作为普通字节数据处理时,ByteBuffer效果最佳 - 一旦您需要将它们转换为对象,其他Java io类通常表现更好并且更易于使用。

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. 如果你不处理内存映射文件,那么你真的不需要打扰ByteBuffer - 你通常使用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. 如果您正在尝试使用基于文件的原始字节数据的最快吞吐量来构建Web服务器,那么ByteBuffer(特别是MappedByteBuffer)是您最好的朋友。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM