如何简单地连接两个 byte
数组?
比如说,
byte a[];
byte b[];
我如何将两个byte
数组连接起来并存储到另一个byte
数组中?
如何简单地连接两个 byte
数组?
比如说,
byte a[];
byte b[];
我如何将两个byte
数组连接起来并存储到另一个byte
数组中?
使用ByteArrayOutputStream
是最优雅的方法。
byte a[];
byte b[];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );
byte c[] = outputStream.toByteArray( );
outputStream.write(c);
,而不需要回去修改创建结果字节数组的那一行。此外,重新排列这些数组也很简单,不像使用arraycopy
方法那样麻烦。 - Wayne UrodaByteArrayOutputStream
构造函数的参数时使用a.length + b.length
。请注意,这种方法仍将所有字节复制到新数组以分配给c[]
!考虑使用ByteBuffer
方法作为一个接近的竞争者,它不会浪费内存。 - Maarten Bodewes最简单的方法:
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);
以下是使用Guava的com.google.common.primitives.Bytes
提供的好的解决方案:
byte[] c = Bytes.concat(a, b);
这种方法的好处在于它具有可变参数签名:
public static byte[] concat(byte[]... arrays)
这意味着您可以在单个方法调用中连接任意数量的数组。
这意味着您可以在单个方法调用中连接任意数量的数组。
另一种可能性是使用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()
仅返回支撑数组,而不考虑偏移量、位置或限制)。
ByteBuffer.allocate(int)
是一个返回实例化的java.nio.HeapByteBuffer
的静态方法,它是ByteBuffer
的子类。.put()
和.compact()
方法以及其他抽象性都已处理好。 - kalefranzcompact()
行,因为它是不正确的。 - Maarten Bodewesbb.flip(); bb.get(result);
而不是byte[] result = bb.array();
来解决这个问题。 - DarqueSanduallocate
方法的说明会发现以下内容:“新缓冲区的位置将为零,其限制将为其容量,其标记将未定义,并且其每个元素都将初始化为零。它将有一个后备数组,其数组偏移量将为零。”因此,对于这个特定的代码片段,在内部分配ByteBuffer
时,这不是一个问题。 - Maarten Bodewes另一种方法是使用一个实用函数(如果您喜欢,可以将其作为通用实用类的静态方法):
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代码,而且非常易读易于维护。
你可以使用第三方库,如Apache Commons Lang等来进行代码整洁化,例如:
byte[] bytes = ArrayUtils.addAll(a, b);
ArrayUtils.addAll(a, b)
和 byte[] c = Bytes.concat(a, b)
,但后者更快。 - Carlos Andrés García如果您像@kalefranz一样更喜欢ByteBuffer
,那么总有可能将两个(甚至更多)byte[]
连接在一行中,就像这样:
byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();
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);
/**
* 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();
}
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”均表示西方Latin 1字符集,该字符集将每个字符编码为单个字节。由于不执行多字节转换,因此字符串中的字符将具有与字节相同的值(除了它们始终被解释为正值,因为char是无符号的)。至少对于Oracle提供的运行时,任何字节都将被正确“解码”,然后再次“编码”。
请注意,字符串会相当大地扩展字节数组,需要额外的内存。字符串也可能被国际化,因此不易删除。字符串也是不可变的,因此其中的值不能被销毁。因此,您不应以这种方式连接敏感数组,也不应将此方法用于较大的字节数组。还需要清楚地指示您正在做什么,因为这种数组连接方法不是常见的解决方案。
System.arrayCopy
、ByteBuffer
以及效率不高但易读的ByteArrayOutputStream
都已经被涵盖在内。我们已经有超过7个重复的答案了,请不要再发布重复内容。 - Maarten Bodewes