Easy way to concatenate two byte arrays

JavaArraysConcatenation

Java Problem Overview


What is the easy way to concatenate two byte arrays?

Say,

byte a[];
byte b[];

How do I concatenate two byte arrays and store it in another byte array?

Java Solutions


Solution 1 - Java

The most elegant way to do this is with a ByteArrayOutputStream.

byte a[];
byte b[];

ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );

byte c[] = outputStream.toByteArray( );

Solution 2 - Java

Most straightforward:

byte[] c = new byte[a.length + b.length];
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);

Solution 3 - Java

Here's a nice solution using Guava's com.google.common.primitives.Bytes:

byte[] c = Bytes.concat(a, b);

The great thing about this method is that it has a varargs signature:

public static byte[] concat(byte[]... arrays)

which means that you can concatenate an arbitrary number of arrays in a single method call.

Solution 4 - Java

Another possibility is using java.nio.ByteBuffer.

Something like

ByteBuffer bb = ByteBuffer.allocate(a.length + b.length + c.length);
bb.put(a);
bb.put(b);
bb.put(c);
byte[] result = bb.array();

// or using method chaining:

byte[] result = ByteBuffer
        .allocate(a.length + b.length + c.length)
        .put(a).put(b).put(c)
        .array();

Note that the array must be appropriately sized to start with, so the allocation line is required (as array() simply returns the backing array, without taking the offset, position or limit into account).

Solution 5 - Java

Another way is to use a utility function (you could make this a static method of a generic utility class if you like):

byte[] concat(byte[]...arrays)
{
    // Determine the length of the result array
    int totalLength = 0;
    for (int i = 0; i < arrays.length; i++)
    {
        totalLength += arrays[i].length;
    }

    // create the result array
    byte[] result = new byte[totalLength];

    // copy the source arrays into the result array
    int currentIndex = 0;
    for (int i = 0; i < arrays.length; i++)
    {
        System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length);
        currentIndex += arrays[i].length;
    }

    return result;
}

Invoke like so:

byte[] a;
byte[] b;
byte[] result = concat(a, b);

It will also work for concatenating 3, 4, 5 arrays, etc.

Doing it this way gives you the advantage of fast arraycopy code which is also very easy to read and maintain.

Solution 6 - Java

You can use third party libraries for Clean Code like Apache Commons Lang and use it like:

byte[] bytes = ArrayUtils.addAll(a, b);
		

Solution 7 - Java

byte[] result = new byte[a.length + b.length];
// copy a to result
System.arraycopy(a, 0, result, 0, a.length);
// copy b to result
System.arraycopy(b, 0, result, a.length, b.length);

Solution 8 - Java

If you prefer ByteBuffer like @kalefranz, there is always the posibility to concatenate two byte[] (or even more) in one line, like this:

byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();

Solution 9 - Java

For two or multiple arrays, this simple and clean utility method can be used:

/**
 * Append the given byte arrays to one big array
 *
 * @param arrays The arrays to append
 * @return The complete array containing the appended data
 */
public static final byte[] append(final byte[]... arrays) {
	final ByteArrayOutputStream out = new ByteArrayOutputStream();
	if (arrays != null) {
		for (final byte[] array : arrays) {
			if (array != null) {
				out.write(array, 0, array.length);
			}
		}
	}
	return out.toByteArray();
}

Solution 10 - Java

Merge two PDF byte arrays

If you are merging two byte arrays which contain PDF, this logic will not work. We need to use a third-party tool like PDFbox from Apache:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mergePdf.addSource(new ByteArrayInputStream(a));
mergePdf.addSource(new ByteArrayInputStream(b));
mergePdf.setDestinationStream(byteArrayOutputStream);
mergePdf.mergeDocuments();
c = byteArrayOutputStream.toByteArray();

Solution 11 - Java

If you don't want to mess with arrays' sizes, just use the magic of string concatenation:

byte[] c = (new String(a, "l1") + new String(b, "l1")).getBytes("l1");

Or define somewhere in your code

// concatenation charset
static final java.nio.charset.Charset cch = java.nio.charset.StandardCharsets.ISO_8859_1;

and use

byte[] c = (new String(a, cch) + new String(b, cch)).getBytes(cch);

This, of course, also works with more than two string concatenations using the + addition operator.


Both "l1" and ISO_8859_1 indicate the Western Latin 1 character set that encodes each character as a single byte. As no multi-byte translations are performed the characters in the string will have the same values as the bytes (except that they will always be interpreted as positive values, as char is unsigned). At least for the Oracle provided runtime, any byte will therefore be correctly "decoded" and then "encoded" again.

Beware that strings do expand the byte array considerately, requiring additional memory. Strings may also be interned and will therefore not easy be removed. Strings are also immutable, so the values inside them cannot be destroyed. You should therefore not concatenate sensitive arrays this way nor should you use this method for larger byte arrays. Giving a clear indication of what you are doing would also be required, as this method of array concatenation is not a common solution.

Solution 12 - Java

This is my way to do it!

public static byte[] concatByteArrays(byte[]... inputs) {
    int i = inputs.length - 1, len = 0;
    for (; i >= 0; i--) {
        len += inputs[i].length;
    }
    byte[] r = new byte[len];
    for (i = inputs.length - 1; i >= 0; i--) {
        System.arraycopy(inputs[i], 0, r, len -= inputs[i].length, inputs[i].length);
    }
    return r;
}

Features:

  • Use varargs (...) to be called with any number of byte[].
  • Use System.arraycopy() that is implemented with machine specific native code, to ensure high speed operation.
  • Create a new byte[] with the exact size that is need it.
  • Allocate little less int variables by reusing the i and len variables.
  • Faster comparison with constants.

Keep in mind:

The better way to do this, is by copy the @Jonathan code. The issue comes from the native variable arrays, because Java create new variables when this data type is passed to another function.

Solution 13 - Java

If you are already loading Guava library you can use static method concat(byte[]... arrays) from com.google.common.primitives.Bytes:

byte[] c = Bytes.concat(a, b);

Here is the standalone source of the concat(byte[]... arrays) method by "Kevin Bourrillion":

public static byte[] concat(byte[]... arrays) {
	int length = 0;
	for (byte[] array : arrays) {
		length += array.length;
	}
	byte[] result = new byte[length];
	int pos = 0;
	for (byte[] array : arrays) {
		System.arraycopy(array, 0, result, pos, array.length);
		pos += array.length;
	}
	return result;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionandroidGuyView Question on Stackoverflow
Solution 1 - JavaKevinView Answer on Stackoverflow
Solution 2 - JavaJonathanView Answer on Stackoverflow
Solution 3 - JavaZoltánView Answer on Stackoverflow
Solution 4 - JavakalefranzView Answer on Stackoverflow
Solution 5 - JavaWayne UrodaView Answer on Stackoverflow
Solution 6 - JavaTomasz PrzybylskiView Answer on Stackoverflow
Solution 7 - JavaJames.XuView Answer on Stackoverflow
Solution 8 - JavaZEuSView Answer on Stackoverflow
Solution 9 - JavaJeroen MeulemeesterView Answer on Stackoverflow
Solution 10 - JavaBala Vignesh BView Answer on Stackoverflow
Solution 11 - JavaJohn McClaneView Answer on Stackoverflow
Solution 12 - JavaDaniel De LeónView Answer on Stackoverflow
Solution 13 - JavamadxView Answer on Stackoverflow