Qual è il modo semplice per concatenare due bytearray?
Dire,
byte a[];
byte b[];
Come posso concatenare due bytearray e memorizzarlo in un altro bytearray?
Qual è il modo semplice per concatenare due bytearray?
Dire,
byte a[];
byte b[];
Come posso concatenare due bytearray e memorizzarlo in un altro bytearray?
Risposte:
Il modo più elegante per farlo è con a ByteArrayOutputStream.
byte a[];
byte b[];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );
byte c[] = outputStream.toByteArray( );
outputStream.write( c );: non è necessario tornare indietro e modificare la riga in cui si crea l'array di byte dei risultati. Inoltre, riordinare le matrici è semplice, diversamente dall'uso del metodo arraycopy.
a.length + b.lengthcome argomento per il ByteArrayOutputStreamcostruttore. Si noti che questo metodo copierà ancora tutti i byte in un nuovo array a cui assegnare c[]! Considera il ByteBuffermetodo un contendente stretto, che non spreca memoria.
Ecco una bella soluzione utilizzando Guava 's com.google.common.primitives.Bytes:
byte[] c = Bytes.concat(a, b);
La cosa grandiosa di questo metodo è che ha una firma varargs:
public static byte[] concat(byte[]... arrays)
il che significa che è possibile concatenare un numero arbitrario di matrici in una singola chiamata di metodo.
Un'altra possibilità sta usando java.nio.ByteBuffer.
Qualcosa di simile a
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();
Si noti che l'array deve essere dimensionato in modo appropriato per iniziare, quindi è necessaria la linea di allocazione (poiché array()restituisce semplicemente l'array di supporto, senza tenere conto dell'offset, della posizione o del limite).
ByteBuffer.allocate(int)è un metodo statico che restituisce un'istanza java.nio.HeapByteBuffer, una sottoclasse di ByteBuffer. I metodi .put()e .compact()- e qualsiasi altra astronomia - sono curati.
compact()in quanto errata.
bb.flip(); bb.get(result);al posto della byte[] result = bb.array();linea.
allocatemetodo rivela quanto segue: "La posizione del nuovo buffer sarà zero, il suo limite sarà la sua capacità, il suo segno sarà indefinito e ciascuno dei suoi elementi verrà inizializzato a zero . Avrà un array di supporto e il suo offset di array sarà zero. " Quindi per questo particolare pezzo di codice, dove l' ByteBufferallocazione è allocata internamente, non è un problema.
Un altro modo è quello di utilizzare una funzione di utilità (è possibile rendere questo un metodo statico di una classe di utilità generica se lo si desidera):
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;
}
Invoca così:
byte[] a;
byte[] b;
byte[] result = concat(a, b);
Funzionerà anche per concatenare 3, 4, 5 array, ecc.
Farlo in questo modo ti dà il vantaggio di un veloce codice di array che è anche molto facile da leggere e mantenere.
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 preferisci ByteBuffercome @kalefranz, c'è sempre la possibilità di concatenare due byte[](o anche più) in una riga, in questo modo:
byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();
Puoi usare librerie di terze parti per Clean Code come Apache Commons Lang e usarlo come:
byte[] bytes = ArrayUtils.addAll(a, b);
ArrayUtils.addAll(a, b)e byte[] c = Bytes.concat(a, b), ma quest'ultimo è più veloce.
Per due o più array, è possibile utilizzare questo metodo di utilità semplice e pulito:
/**
* 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 si stanno unendo array di due byte che contengono PDF, questa logica non funzionerà. Dobbiamo utilizzare uno strumento di terze parti come PDFbox di Apache:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mergePdf.addSource(new ByteArrayInputStream(a));
mergePdf.addSource(new ByteArrayInputStream(b));
mergePdf.setDestinationStream(byteArrayOutputStream);
mergePdf.mergeDocuments();
c = byteArrayOutputStream.toByteArray();
Se non vuoi fare confusione con le dimensioni degli array, usa semplicemente la magia della concatenazione di stringhe:
byte[] c = (new String(a, "l1") + new String(b, "l1")).getBytes("l1");
O definisci da qualche parte nel tuo codice
// concatenation charset
static final java.nio.charset.Charset cch = java.nio.charset.StandardCharsets.ISO_8859_1;
e usare
byte[] c = (new String(a, cch) + new String(b, cch)).getBytes(cch);
Questo, ovviamente, funziona anche con più di due concatenazioni di stringhe usando l' +operatore addizione.
Entrambi "l1"e ISO_8859_1indicano il set di caratteri Western Latin 1 che codifica ogni carattere come un singolo byte. Poiché non vengono eseguite traduzioni multi-byte, i caratteri nella stringa avranno gli stessi valori dei byte (tranne per il fatto che saranno sempre interpretati come valori positivi, poiché charnon è firmato). Almeno per il runtime fornito da Oracle, qualsiasi byte verrà quindi correttamente "decodificato" e quindi "codificato" di nuovo.
Attenzione che le stringhe espandono considerevolmente l'array di byte, richiedendo memoria aggiuntiva. Le stringhe possono anche essere internate e pertanto non saranno facili da rimuovere. Anche le stringhe sono immutabili, quindi i valori al loro interno non possono essere distrutti. Pertanto, non è necessario concatenare gli array sensibili in questo modo né utilizzare questo metodo per array di byte più grandi. Sarebbe anche necessario fornire una chiara indicazione di ciò che si sta facendo, poiché questo metodo di concatenazione di array non è una soluzione comune.
Questo è il mio modo di farlo!
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;
}
Caratteristiche :
...) per essere chiamato con qualsiasi numero di byte [].System.arraycopy()quello implementato con codice nativo specifico della macchina, per garantire un funzionamento ad alta velocità.intvariabili riutilizzando le variabili ie len.Ricorda :
Il modo migliore per farlo è copiare il codice @Jonathan . Il problema deriva dalle matrici di variabili native, poiché Java crea nuove variabili quando questo tipo di dati viene passato a un'altra funzione.
System.arrayCopy,ByteBuffere il - non così efficiente ma leggibile -ByteArrayOutputStreamsono stati tutti coperti. Abbiamo più di 7 duplicati delle risposte fornite qui. Per favore, non pubblicare altri duplicati.