Apa cara mudah untuk menggabungkan dua byte
array?
Mengatakan,
byte a[];
byte b[];
Bagaimana cara menggabungkan dua byte
array dan menyimpannya di byte
array lain ?
Apa cara mudah untuk menggabungkan dua byte
array?
Mengatakan,
byte a[];
byte b[];
Bagaimana cara menggabungkan dua byte
array dan menyimpannya di byte
array 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.length
sebagai argumen untuk ByteArrayOutputStream
konstruktor. Perhatikan bahwa metode ini masih akan menyalin semua byte ke array baru untuk ditugaskan c[]
! Pertimbangkan ByteBuffer
metode 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.
allocate
metode 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 ByteBuffer
dialokasikan 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 ByteBuffer
seperti @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_1
menunjukkan 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 char
tidak 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.int
variabel dengan menggunakan kembali variabel i
dan 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
,ByteBuffer
dan - tidak begitu efisien tetapi dapat dibaca -ByteArrayOutputStream
semuanya telah dibahas. Kami memiliki lebih dari 7 dupes jawaban yang diberikan di sini. Tolong jangan memposting dupes lagi.