Easy way to concatenate two byte arrays
连接两个
说,
1 2 | byte a[]; byte b[]; |
如何连接两个
最优雅的方法是使用
1 2 3 4 5 6 7 8 | byte a[]; byte b[]; ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); outputStream.write( a ); outputStream.write( b ); byte c[] = outputStream.toByteArray( ); |
最直接的:
1 2 3 |
这是一个很好的解决方案,使用了Guava的
1 | byte[] c = Bytes.concat(a, b); |
这个方法的好处在于它有一个varargs签名:
1 | public static byte[] concat(byte[]... arrays) |
这意味着您可以在单个方法调用中连接任意数量的数组。
另一种可能是使用
类似的东西
1 2 3 4 5 6 7 8 9 10 11 12 | 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(); |
请注意,数组必须适当地调整大小才能开始,因此需要分配行(因为
另一种方法是使用实用程序函数(如果愿意,您可以将其作为通用实用程序类的静态方法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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; } |
像这样调用:
1 2 3 | byte[] a; byte[] b; byte[] result = concat(a, b); |
它还可以连接3、4、5个数组等。
这样做可以使您获得快速的arraycopy代码的优势,它也非常容易读取和维护。
您可以将第三方库用于ApacheCommonsLang之类的干净代码,并使用它:
1 | byte[] bytes = ArrayUtils.addAll(a, b); |
1 2 3 4 5 |
如果您喜欢像@kalefranz那样的
1 | byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array(); |
对于两个或多个数组,可以使用这种简单而干净的实用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * 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(); } |
如果不想弄乱数组的大小,只需使用字符串连接的魔力:
或者在代码中定义
1 2 | // concatenation charset static final java.nio.charset.Charset cch = java.nio.charset.StandardCharsets.ISO_8859_1; |
使用
当然,这也适用于使用
注意,字符串确实会适当地扩展字节数组,需要额外的内存。字符串也可能被截留,因此不容易被删除。字符串也是不可变的,因此不能破坏其中的值。因此,不应以这种方式连接敏感数组,也不应将此方法用于较大的字节数组。由于这种数组连接方法不是一种常见的解决方案,因此还需要清楚地指示您正在执行的操作。
这是我的方法!
1 2 3 4 5 6 7 8 9 10 11 | 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; } |
特征:
- 使用varargs(
... )调用任意数量的字节[]。 - 使用由机器特定的本机代码实现的
System.arraycopy() ,以确保高速运行。 - 创建一个具有所需大小的新字节[]。
- 通过重用
i 和len 变量,分配较少的int 变量。 - 与常量比较更快。
记住:
更好的方法是复制@jonathan代码。问题来自本地变量数组,因为Java在将数据类型传递给另一个函数时创建新变量。
合并两个PDF字节数组
如果合并包含PDF的两个字节数组,则此逻辑将不起作用。我们需要使用第三方工具,如Apache的pdfbox:
1 2 3 4 5 6 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); mergePdf.addSource(new ByteArrayInputStream(a)); mergePdf.addSource(new ByteArrayInputStream(b)); mergePdf.setDestinationStream(byteArrayOutputStream); mergePdf.mergeDocuments(); c = byteArrayOutputStream.toByteArray(); |