Java - ByteBuffer or ArrayList <Byte>?
I recently created a wrapper to read and write data to an array byte
. I used to do this ArrayList<Byte>
, but I was wondering if this is the most efficient way to do it, because:
-
addAll()
doesn't work with arraysbyte
(even usingArrays.asList()
that returns meList<Byte[]>
). To fix this, I just loop and addbyte
in each loop, but I suppose this involves a lot of function calls and therefore has performance. - The same happens when receiving
byte[]
fromArrayList
. I cannot cast frombyte[]
tobyte[]
, so I have to use a loop for that. - I suppose storing a byte instead of a byte uses more memory.
I know that ByteArrayInputStream
u ByteArrayOutputStream
can be used for this, but it has some disadvantages:
- I wanted to implement methods to read various types of data in different byte orders (eg
readInt
,readLEInt
,readUInt
etc.), while these classes can read or write a byte or array of bytes is not a problem, because I can fix it in the wrapper ... But here comes the second problem. - I wanted to be able to write and read at the same time because I am using this to unzip some files. And so to create a wrapper for this, I would need to include both
ByteArrayInputStream
andByteArrayOutputStream
. I don't know if they can be synchronized in any way or if I have to write all the data of one to the other every time I write to the wrapper.
So here's my question: would the use be ByteBuffer
more efficient? I know what you can take integers
, floats
etc. From there, even having the ability to change the byte order. I was wondering if there is a real performance change between using ByteBuffer
and ArrayList<Byte>
.
source to share
Definitely ByteBuffer or ByteArrayOutputStream . In your case, ByteBuffer seems fine. Check out the Javadoc as it has good techniques. For putInt / getInt etc. You can set the order (from those 4 bytes)
byteBuffer.order(ByteBuffer.LITTLE_ENDIAN);
With files, you can use getChannel()
or variations and then use MappedByteBuffer
.
ByteBuffer can wrap a byte array or allocate.
source to share
ByteBuffer is a wrapper class around a byte array, it doesn't have a dynamic size like ArrayList, but it consumes less memory per byte and is faster. If you know the size you want then use a ByteBuffer, if you don't, then you can use a ByteArrayOutputStream (and possibly wrapped ObjectOutputStream, it has some methods for writing different kinds of data). To read the data that you wrote in ByteArrayOutputStream you can extend ByteArrayOutputStream and then you can access buf [] and count fields, these fields are protected so you can access them from extension class, it looks like this:
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];
}
}
so that you can use some of the methods in the extending class to read multiple bytes from the underlying buffer without having to make a copy of your content every time as the byByteArray () method does.
source to share