首页 文章

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

提问于
浏览
215

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

说,

byte a[];
byte b[];

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

12 回答

  • 283

    最简单的:

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

    最优雅的方法是使用 ByteArrayOutputStream .

    byte a[];
    byte b[];
    
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
    outputStream.write( a );
    outputStream.write( b );
    
    byte c[] = outputStream.toByteArray( );
    
  • 9

    这是使用Guavacom.google.common.primitives.Bytes 的一个很好的解决方案:

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

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

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

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

  • 10

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

  • 26

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

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

    您可以使用第三方库来清理代码,例如Apache Commons Lang,并使用它:

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

    如果您喜欢像@kalefranz这样的 ByteBuffer ,那么总是可以在一行中连接两个 byte[] (甚至更多),如下所示:

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

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

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

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

    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提供的运行时,任何字节都将正确"decoded",然后再次"encoded" .

    请注意字符串确实会扩展字节数组,需要额外的内存 . 字符串也可能被实习,因此不容易被删除 . 字符串也是不可变的,因此它们内部的值不能被销毁 . 因此,您不应该以这种方式连接敏感数组,也不应该将此方法用于较大的字节数组 . 还需要明确指出您正在做什么,因为这种阵列级联方法不是常见的解决方案 .

  • 56

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

    Features

    • 使用任意数量的byte []调用varargs( ... ) .

    • 使用通过机器特定的本机代码实现的 System.arraycopy() ,以确保高速运行 .

    • 使用所需的确切大小创建一个新的byte [] .

    • 通过重用 ilen 变量来分配少量 int 变量 .

    • 与常量的比较更快 .

    Keep in mind

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

相关问题