35

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 ?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
Damir
  • 54,277
  • 94
  • 246
  • 365

5 Answers5

59

You can use a ByteBuffer.

ByteBuffer target = ByteBuffer.wrap(bigByteArray);
target.put(small1);
target.put(small2);
...;
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
josefx
  • 15,506
  • 6
  • 38
  • 63
  • 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. – cthulhu Jan 28 '11 at 11:42
  • 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. – Mark Jeronimus Nov 14 '13 at 14:25
  • 2
    @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. – josefx Nov 15 '13 at 12:54
  • 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. – Evgeny Veretennikov Aug 22 '17 at 12:12
25

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.

Community
  • 1
  • 1
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
13

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();
}
Ian Jones
  • 1,998
  • 1
  • 17
  • 17
  • Just watch this https://android.googlesource.com/platform/libcore/+/5d930ca/luni/src/main/java/java/io/ByteArrayOutputStream.java Your code is very ineffective. – Master Apr 18 '20 at 20:23
6

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

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • 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). – Joachim Sauer Jan 28 '11 at 11:35
  • @sean: please use getBytes(Charset.forName("ASCII")) or similar in next samples (as getBytes() depends on the runtime system for the character encoding) – Maarten Bodewes Oct 27 '11 at 12:46
2

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();
}
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185