I have one big byte[] array and lot of small byte arrays ( length of big array is sum of lengths small arrays). Is there maybe some quick method to copy one array to another from starting position to ending, not to use for loop for every byte manually ?
5 Answers
You can use a ByteBuffer.
ByteBuffer target = ByteBuffer.wrap(bigByteArray);
target.put(small1);
target.put(small2);
...;
4 Comments
cthulhu
Pretty sure this'd use a similar code internally as was suggested by other answers. Upvoted, it's usually better to use a built-in method than re-invent the wheel.
Mark Jeronimus
Downvoted. This doesn't account for the case where the final length of the big array is unknown at the time the first partial arrays are delivered.
josefx
@Zom-B the question starts of with "I have one big byte array" so it looked like the size of the array is alread known beforehand.
Evgeny Veretennikov
Use
ByteBuffer.allocate(size), if you need array of given size, but don't have it yet. Then, invoke target.getArray() after all target.put() invocations.Use System.arraycopy().
You could also apply the solution from a previous answer of mine. Note that for primitive types such as byte you'll have to produce separate versions (one for each primitive type), as generics don't work there.
4 Comments
Sean Patrick Floyd
+1 for your previous answer. It will also work for primitive types, if you let it accept to Object parameters instead of two T[]s. But that does of course mean there's no compile-time checking.
Joachim Sauer
@Sean: unfortunately there's no
Arrays.copyOf() that takes an Object.Sean Patrick Floyd
argh, confused that with
System.arrayCopy()Dori
seems weird this is a
System method!Or you could use a ByteArrayOutputStream (Although it creates the resulting array for you, rather than copying into an existing array as you asked).
public byte[] concatenateByteArrays(List<byte[]> blocks) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
for (byte[] b : blocks) {
os.write(b, 0, b.length);
}
return os.toByteArray();
}
1 Comment
Master
Just watch this android.googlesource.com/platform/libcore/+/5d930ca/luni/src/… Your code is very ineffective.
Sample Implementation
public static void copySmallArraysToBigArray(final byte[][] smallArrays,
final byte[] bigArray){
int currentOffset = 0;
for(final byte[] currentArray : smallArrays){
System.arraycopy(
currentArray, 0,
bigArray, currentOffset,
currentArray.length
);
currentOffset += currentArray.length;
}
}
Test Code
public static void main(final String[] args){
final byte[][] smallArrays =
{
"The" .getBytes(),
" Quick" .getBytes(),
" Brown" .getBytes(),
" Fox" .getBytes()
};
final byte[] bigArray = "The Small Mauve Cat".getBytes();
copySmallArraysToBigArray(smallArrays, bigArray);
System.out.println(new String(bigArray));
}
Output:
The Quick Brown Fox
2 Comments
Joachim Sauer
I'd remove the check and the throwing of the exception, because
System.arraycopy() already throws an IndexOutOfBoundsException when the indices are out of bounds (and that exception gives a bit more information as well).Maarten Bodewes
@sean: please use getBytes(Charset.forName("ASCII")) or similar in next samples (as getBytes() depends on the runtime system for the character encoding)
Here is another solution which also uses ByteBuffer:
public static byte[] toByteArray(List<byte[]> bytesList)
{
int size = 0;
for (byte[] bytes : bytesList)
{
size += bytes.length;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(size);
for (byte[] bytes : bytesList)
{
byteBuffer.put(bytes);
}
return byteBuffer.array();
}