Qual é a maneira mais fácil de concatenar duas byte
matrizes?
Dizer,
byte a[];
byte b[];
Como concatenar duas byte
matrizes e armazená-las em outra byte
matriz?
Qual é a maneira mais fácil de concatenar duas byte
matrizes?
Dizer,
byte a[];
byte b[];
Como concatenar duas byte
matrizes e armazená-las em outra byte
matriz?
Respostas:
A maneira mais elegante de fazer isso é com a ByteArrayOutputStream
.
byte a[];
byte b[];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );
byte c[] = outputStream.toByteArray( );
outputStream.write( c );
- você não precisa voltar e editar a linha em que cria a matriz de bytes resultante. Além disso, reordenar as matrizes é simples, ao contrário do método arraycopy.
a.length + b.length
como argumento o ByteArrayOutputStream
construtor. Observe que esse método ainda copiará todos os bytes para uma nova matriz à qual atribuir c[]
! Considere o ByteBuffer
método como um concorrente próximo, que não desperdiça memória.
Aqui está uma boa solução usando goiaba 's com.google.common.primitives.Bytes
:
byte[] c = Bytes.concat(a, b);
O melhor deste método é que ele possui uma assinatura varargs:
public static byte[] concat(byte[]... arrays)
o que significa que você pode concatenar um número arbitrário de matrizes em uma única chamada de método.
Outra possibilidade está usando java.nio.ByteBuffer
.
Algo como
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();
Observe que a matriz deve ser dimensionada adequadamente para começar, portanto a linha de alocação é necessária (como array()
simplesmente retorna a matriz de suporte, sem levar em consideração o deslocamento, a posição ou o limite).
ByteBuffer.allocate(int)
é um método estático que retorna uma java.nio.HeapByteBuffer
subclasse instanciada ByteBuffer
. Os métodos .put()
e .compact()
- e qualquer outra abstração - são resolvidos.
compact()
Linha removida por estar incorreta.
bb.flip(); bb.get(result);
em vez da byte[] result = bb.array();
linha.
allocate
método revela o seguinte: "A posição do novo buffer será zero, seu limite será sua capacidade, sua marca será indefinida e cada um de seus elementos será inicializado como zero Ele terá uma matriz de apoio e seu deslocamento da matriz será zero. " Portanto, para este determinado pedaço de código, onde o ByteBuffer
é alocada internamente, não é um problema.
Outra maneira é usar uma função de utilitário (você pode fazer disso um método estático de uma classe de utilitário genérica, se quiser):
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;
}
Invoque assim:
byte[] a;
byte[] b;
byte[] result = concat(a, b);
Também funcionará para concatenar 3, 4, 5 matrizes etc.
Fazer dessa maneira oferece a vantagem do código rápido de cópia de matriz, que também é muito fácil de ler e manter.
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);
Se você preferir ByteBuffer
como @kalefranz, sempre há a possibilidade de concatenar duas byte[]
(ou até mais) em uma linha, assim:
byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();
Você pode usar bibliotecas de terceiros para o Código Limpo como o Apache Commons Lang e usá-lo como:
byte[] bytes = ArrayUtils.addAll(a, b);
ArrayUtils.addAll(a, b)
e byte[] c = Bytes.concat(a, b)
, mas o último é mais rápido.
Para duas ou várias matrizes, este método utilitário simples e limpo pode ser usado:
/**
* 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();
}
Se você estiver mesclando matrizes de dois bytes que contêm PDF, essa lógica não funcionará. Precisamos usar uma ferramenta de terceiros como o PDFbox do Apache:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mergePdf.addSource(new ByteArrayInputStream(a));
mergePdf.addSource(new ByteArrayInputStream(b));
mergePdf.setDestinationStream(byteArrayOutputStream);
mergePdf.mergeDocuments();
c = byteArrayOutputStream.toByteArray();
Se você não quiser mexer no tamanho das matrizes, use a mágica da concatenação de strings:
byte[] c = (new String(a, "l1") + new String(b, "l1")).getBytes("l1");
Ou defina algum lugar no seu código
// concatenation charset
static final java.nio.charset.Charset cch = java.nio.charset.StandardCharsets.ISO_8859_1;
E use
byte[] c = (new String(a, cch) + new String(b, cch)).getBytes(cch);
Obviamente, isso também funciona com mais de duas concatenações de cadeias usando o +
operador de adição.
Ambos "l1"
e ISO_8859_1
indicam o conjunto de caracteres 1 em latim ocidental que codifica cada caractere como um único byte. Como nenhuma conversão de vários bytes é executada, os caracteres na sequência terão os mesmos valores que os bytes (exceto que eles sempre serão interpretados como valores positivos, como char
não são assinados). Pelo menos para o tempo de execução fornecido pelo Oracle, qualquer byte será corretamente "decodificado" e depois "codificado" novamente.
Cuidado que as strings expandem consideravelmente a matriz de bytes, exigindo memória adicional. As strings também podem ser internadas e, portanto, não serão fáceis de remover. As strings também são imutáveis, portanto, os valores dentro delas não podem ser destruídos. Portanto, você não deve concatenar matrizes confidenciais dessa maneira nem usar esse método para matrizes de bytes maiores. Também é necessário fornecer uma indicação clara do que você está fazendo, pois esse método de concatenação de matriz não é uma solução comum.
Esta é a minha maneira de fazê-lo!
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;
}
Características :
...
) para ser chamado com qualquer número de bytes [].System.arraycopy()
implementado com código nativo específico da máquina, para garantir a operação em alta velocidade.int
variáveis, reutilizando as variáveis i
e len
.Tenha em mente :
A melhor maneira de fazer isso é copiando o código @Jonathan . O problema vem das matrizes de variáveis nativas, porque o Java cria novas variáveis quando esse tipo de dados é passado para outra função.
System.arrayCopy
,ByteBuffer
e a - não tão eficiente, mas legível -ByteArrayOutputStream
foram todos cobertos. Temos mais de 7 enganos das respostas dadas aqui. Por favor, não poste mais bobagens.