连接两个字节数组的简单方法

连接两个byte数组的简单方法是什么?

说,

byte a[];
byte b[];

如何连接两个byte数组并将其存储在另一个byte数组中?

316067 次浏览

最简单的:

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);
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);

最优雅的方法是使用ByteArrayOutputStream

byte a[];
byte b[];


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


byte c[] = outputStream.toByteArray( );

另一种方法是使用一个实用函数(如果你喜欢,你可以让它成为一个通用实用类的静态方法):

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;
}

像这样调用:

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

它也可以用于连接3,4,5个数组等。

这样做可以获得快速arraycopy代码的优势,而且非常易于阅读和维护。

另一种可能性是使用java.nio.ByteBuffer

类似的

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();

请注意,数组必须在开始时具有适当的大小,因此分配行是必需的(因为array()只是返回支持数组,而不考虑偏移量、位置或限制)。

下面是使用番石榴com.google.common.primitives.Bytes的一个很好的解决方案:

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

这个方法的伟大之处在于它有一个varargs签名:

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

这意味着您可以在单个方法调用中连接任意数量的数组。

如果你喜欢像@kalefranz那样的ByteBuffer,总是有可能将两个byte[](甚至更多)连接在一行中,就像这样:

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

对于两个或多个数组,可以使用这个简单而干净的实用程序方法:

/**
* 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();
}

你可以使用第三方库,如Apache Commons Lang,并像这样使用它:

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

合并两个PDF字节数组

如果合并两个包含PDF的字节数组,则此逻辑将不起作用。我们需要使用第三方工具,如Apache中的PDFbox:

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

这就是我的方法!

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(),以确保高速运行。
  • 创建一个新字节[],其大小与所需要的大小一致。
  • 通过重用ilen变量,分配更少的int变量。
  • 与常数比较更快。

记住:

更好的方法是复制@Jonathan代码。问题来自本地变量数组,因为当此数据类型传递给另一个函数时,Java会创建新的变量。

如果你不想打乱数组的大小,只需使用字符串连接的魔法:

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

或者在代码的某个地方定义

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

和使用

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

当然,这也适用于使用+加法运算符的两个以上的字符串连接。


"l1"ISO_8859_1都表示将每个字符编码为单个字节的西方拉丁1字符集。由于没有执行多字节转换,字符串中的字符将具有与字节相同的值(除了它们总是被解释为正值,因为char是无符号的)。至少对于Oracle提供的运行时,任何字节都将因此被正确地“解码”,然后再次“编码”。

注意,字符串确实会适当地扩展字节数组,需要额外的内存。字符串也可能被扣押,因此不容易被删除。字符串也是不可变的,所以其中的值不能被销毁。因此,不应以这种方式连接敏感数组,也不应将此方法用于较大的字节数组。还需要清楚地表明您正在做什么,因为这种数组连接方法不是常见的解决方案。

如果你已经加载了番石榴库,你可以从com.google.common.primitives.Bytes中使用静态方法concat(byte[]... arrays):

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

下面是由“Kevin bourrillion”编写的concat(byte[]... arrays)方法的独立:

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;
}