Answers:
最优雅的方法是使用ByteArrayOutputStream
。
byte a[];
byte b[];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );
byte c[] = outputStream.toByteArray( );
outputStream.write( c );
-无需返回并编辑在创建结果字节数组的行。而且,与使用arraycopy方法不同,对数组重新排序很简单。
a.length + b.length
用作ByteArrayOutputStream
构造函数的参数。请注意,此方法仍会将所有字节复制到一个新数组中,以分配给c[]
!考虑该ByteBuffer
方法是一个紧密的竞争者,它不会浪费内存。
另一种可能性是使用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()
方法-和任何其他抽象内斯-被照顾。
compact()
因为它不正确,所以删除了该行。
bb.flip(); bb.get(result);
代替byte[] result = bb.array();
行发行来解决此问题。
allocate
方法可以发现以下内容:“新缓冲区的位置将为零,其极限将是其容量,其标记将是未定义的,并且其每个元素都将初始化为零它将有一个支持数组,并且其数组偏移量将为零。” 因此,对于在内部分配的特定代码段ByteBuffer
,这不是问题。
另一种方法是使用实用程序功能(如果愿意,可以将其设为通用实用程序类的静态方法):
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代码的优点,该代码也非常易于阅读和维护。
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);
如果您更ByteBuffer
喜欢@kalefranz,总是可以byte[]
在一行中连接两个(或更多),如下所示:
byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();
您可以将第三方库用于干净代码,例如Apache Commons Lang,并按以下方式使用它:
byte[] bytes = ArrayUtils.addAll(a, b);
ArrayUtils.addAll(a, b)
和byte[] c = Bytes.concat(a, b)
,但是后者更快。
对于两个或多个数组,可以使用此简单而干净的实用程序方法:
/**
* 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();
}
如果要合并两个包含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();
如果您不想弄乱数组的大小,只需使用字符串连接的魔力即可:
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提供的运行时,因此将正确地对任何字节进行“解码”,然后再次进行“编码”。
请注意,字符串确实会适当地扩展字节数组,这需要额外的内存。弦线也可能被扣留,因此不容易去除。字符串也是不可变的,因此不能破坏字符串中的值。因此,您不应以这种方式连接敏感数组,也不应将这种方法用于较大的字节数组。由于这种数组级联方法不是常见的解决方案,因此也需要清楚地表明您在做什么。
这是我的方法!
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 []进行调用。System.arraycopy()
了与机器特定的本地代码来实现,以确保高速运转。int
通过重用i
和len
变量来分配较少的变量。注意事项:
更好的方法是复制@Jonathan代码。问题出在本机变量数组上,因为当此数据类型传递给另一个函数时,Java会创建新变量。
System.arrayCopy
,ByteBuffer
和-不那么有效,但可读的-ByteArrayOutputStream
都被覆盖。在这里给出的答案中,我们有7个以上的重复。请不要再发布任何重复信息。