Apa cara mudah untuk menggabungkan dua bytearray?
Mengatakan,
byte a[];
byte b[];
Bagaimana cara menggabungkan dua bytearray dan menyimpannya di bytearray lain ?
Apa cara mudah untuk menggabungkan dua bytearray?
Mengatakan,
byte a[];
byte b[];
Bagaimana cara menggabungkan dua bytearray dan menyimpannya di bytearray lain ?
Jawaban:
Cara paling elegan untuk melakukan ini adalah dengan a ByteArrayOutputStream.
byte a[];
byte b[];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );
byte c[] = outputStream.toByteArray( );
outputStream.write( c );- Anda tidak harus kembali dan mengedit baris tempat Anda membuat array byte hasil. Juga, memesan ulang array itu sederhana, tidak seperti menggunakan metode arraycopy.
a.length + b.lengthsebagai argumen untuk ByteArrayOutputStreamkonstruktor. Perhatikan bahwa metode ini masih akan menyalin semua byte ke array baru untuk ditugaskan c[]! Pertimbangkan ByteBuffermetode ini sebagai pesaing dekat, yang tidak menghabiskan memori.
Berikut adalah solusi yang bagus menggunakan Jambu 's com.google.common.primitives.Bytes:
byte[] c = Bytes.concat(a, b);
Hal yang hebat tentang metode ini adalah ia memiliki tanda tangan varargs:
public static byte[] concat(byte[]... arrays)
yang berarti bahwa Anda dapat menggabungkan jumlah array sewenang-wenang dalam satu pemanggilan metode tunggal.
Kemungkinan lain adalah menggunakan java.nio.ByteBuffer.
Sesuatu seperti
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();
Perhatikan bahwa array harus berukuran tepat untuk memulainya, sehingga garis alokasi diperlukan ( array()hanya mengembalikan array dukungan, tanpa memperhitungkan offset, posisi, atau batas).
ByteBuffer.allocate(int)adalah metode statis yang mengembalikan instantiated java.nio.HeapByteBuffer, subclass dari ByteBuffer. Metode .put()dan .compact()- dan keabstrakan lainnya - dijaga.
compact()baris karena tidak benar.
bb.flip(); bb.get(result);sebagai ganti byte[] result = bb.array();baris.
allocatemetode ini mengungkapkan hal berikut: "Posisi buffer baru akan nol, batasnya adalah kapasitasnya, tandanya akan tidak ditentukan, dan masing-masing elemennya akan diinisialisasi ke nol Ini akan memiliki array pendukung, dan offset arraynya akan nol. " Jadi untuk ini khusus potongan kode, di mana ByteBufferdialokasikan secara internal, itu tidak masalah.
Cara lain adalah dengan menggunakan fungsi utilitas (Anda bisa menjadikan ini metode statis kelas utilitas generik jika Anda mau):
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;
}
Ajukan seperti ini:
byte[] a;
byte[] b;
byte[] result = concat(a, b);
Ini juga akan berfungsi untuk menggabungkan 3, 4, 5 array, dll.
Melakukannya dengan cara ini memberi Anda keuntungan dari kode arraycopy cepat yang juga sangat mudah dibaca dan dipelihara.
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);
Jika Anda lebih suka ByteBufferseperti @kalefranz, selalu ada kemungkinan untuk menggabungkan dua byte[](atau bahkan lebih) dalam satu baris, seperti ini:
byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();
Anda dapat menggunakan perpustakaan pihak ketiga untuk Kode Bersih seperti Apache Commons Lang dan menggunakannya seperti:
byte[] bytes = ArrayUtils.addAll(a, b);
ArrayUtils.addAll(a, b)dan byte[] c = Bytes.concat(a, b), tetapi yang terakhir lebih cepat.
Untuk dua atau beberapa array, metode utilitas sederhana dan bersih ini dapat digunakan:
/**
* 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();
}
Jika Anda menggabungkan array dua byte yang berisi PDF, logika ini tidak akan berfungsi. Kita perlu menggunakan alat pihak ketiga seperti PDFbox dari Apache:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mergePdf.addSource(new ByteArrayInputStream(a));
mergePdf.addSource(new ByteArrayInputStream(b));
mergePdf.setDestinationStream(byteArrayOutputStream);
mergePdf.mergeDocuments();
c = byteArrayOutputStream.toByteArray();
Jika Anda tidak ingin mengacaukan dengan ukuran array, cukup gunakan keajaiban penggabungan string:
byte[] c = (new String(a, "l1") + new String(b, "l1")).getBytes("l1");
Atau tentukan di suatu tempat dalam kode Anda
// concatenation charset
static final java.nio.charset.Charset cch = java.nio.charset.StandardCharsets.ISO_8859_1;
dan gunakan
byte[] c = (new String(a, cch) + new String(b, cch)).getBytes(cch);
Ini, tentu saja, juga bekerja dengan lebih dari dua rangkaian string menggunakan +operator tambahan.
Keduanya "l1"dan ISO_8859_1menunjukkan set karakter Latin 1 Barat yang mengkodekan setiap karakter sebagai byte tunggal. Karena tidak ada terjemahan multi-byte yang dilakukan, karakter dalam string akan memiliki nilai yang sama dengan byte (kecuali bahwa mereka akan selalu ditafsirkan sebagai nilai positif, seperti yang chartidak ditandatangani). Setidaknya untuk runtime yang disediakan Oracle, byte apa pun karena itu akan benar "diterjemahkan" dan kemudian "dikodekan" lagi.
Berhati-hatilah karena string perlu memperluas array byte secara matang, membutuhkan memori tambahan. String juga dapat diinternir dan karenanya tidak mudah dihilangkan. String juga tidak dapat diubah, sehingga nilai-nilai di dalamnya tidak dapat dihancurkan. Karena itu Anda tidak boleh menggabungkan array sensitif dengan cara ini atau Anda harus menggunakan metode ini untuk array byte yang lebih besar. Memberikan indikasi yang jelas tentang apa yang Anda lakukan juga akan diperlukan, karena metode penggabungan array ini bukanlah solusi yang umum.
Ini cara saya melakukannya!
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;
}
Fitur :
...) untuk dipanggil dengan sejumlah byte [].System.arraycopy()yang diterapkan dengan kode asli khusus mesin, untuk memastikan operasi kecepatan tinggi.intvariabel dengan menggunakan kembali variabel idan len.Ingatlah :
Cara yang lebih baik untuk melakukan ini, adalah dengan menyalin kode @ Jonathan . Masalahnya berasal dari array variabel asli, karena Java membuat variabel baru ketika tipe data ini diteruskan ke fungsi lain.
System.arrayCopy,ByteBufferdan - tidak begitu efisien tetapi dapat dibaca -ByteArrayOutputStreamsemuanya telah dibahas. Kami memiliki lebih dari 7 dupes jawaban yang diberikan di sini. Tolong jangan memposting dupes lagi.