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

时间:2011-04-01 12:09:24

标签: java arrays concatenation

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

说,

byte a[];
byte b[];

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

13 个答案:

答案 0 :(得分:332)

最优雅的方法是使用ByteArrayOutputStream

byte a[];
byte b[];

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

byte c[] = outputStream.toByteArray( );

答案 1 :(得分:292)

最直截了当:

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

答案 2 :(得分:59)

使用Guavacom.google.common.primitives.Bytes

,这是一个很好的解决方案
byte[] c = Bytes.concat(a, b);

关于这种方法的好处是它有一个varargs签名:

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

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

答案 3 :(得分:26)

另一种可能性是使用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()只返回支持数组,而不考虑偏移量,位置或限制)。

答案 4 :(得分:12)

另一种方法是使用实​​用程序函数(如果您愿意,可以将其设置为泛型实用程序类的静态方法):

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个数组等。

这样做可以为您提供快速阵列代码的优势,这也很容易阅读和维护。

答案 5 :(得分:10)

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

答案 6 :(得分:10)

您可以将第三方库用于清洁代码,例如Apache Commons Lang,并将其用作:

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

答案 7 :(得分:9)

如果你更喜欢ByteBuffer喜欢@kalefranz,总有可能在一行中连接两个byte[](甚至更多),如下所示:

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

答案 8 :(得分:5)

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

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

答案 9 :(得分:1)

如果您不想弄乱数组的大小,只需使用字符串连接的魔力:

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均表示将每个字符编码为单个字节的Western Latin 1字符集。由于不执行多字节转换,因此字符串中的字符将具有与字节相同的值(除非它们将始终被解释为正值,因为char是无符号的)。至少对于Oracle提供的运行时,因此将正确地对任何字节进行“解码”,然后再次进行“编码”。

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

答案 10 :(得分:0)

合并两个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();

答案 11 :(得分:0)

这是我的方法!

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

功能

  • 使用任意数量的byte []来调用varargs(...)。
  • 使用通过机器特定的本机代码实现的System.arraycopy(),以确保高速运行。
  • 使用所需的确切大小创建一个新的byte []。
  • 重复使用inti变量,分配少量len变量。
  • 与常数比较更快。

请记住

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

答案 12 :(得分:0)

如果您已经在加载 Guava 库,您可以使用来自 concat(byte[]... arrays) 的静态方法 com.google.common.primitives.Bytes

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

这是“Kevin Bourrillion”的 concat(byte[]... arrays) 方法的独立 source

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