İki byte
diziyi birleştirmenin kolay yolu nedir ?
Söyle,
byte a[];
byte b[];
İki byte
diziyi nasıl birleştiririm ve başka bir byte
dizide nasıl depolayabilirim ?
İki byte
diziyi birleştirmenin kolay yolu nedir ?
Söyle,
byte a[];
byte b[];
İki byte
diziyi nasıl birleştiririm ve başka bir byte
dizide nasıl depolayabilirim ?
Yanıtlar:
Bunu yapmanın en zarif yolu a ByteArrayOutputStream
.
byte a[];
byte b[];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
outputStream.write( a );
outputStream.write( b );
byte c[] = outputStream.toByteArray( );
outputStream.write( c );
- geri dönüp sonuç bayt dizisini oluşturduğunuz satırı düzenlemenize gerek yoktur. Ayrıca, dizikopi yönteminden farklı olarak dizileri yeniden sıralamak basittir.
a.length + b.length
için argüman olarak kullandığınızdan emin olun ByteArrayOutputStream
. Bu yöntemin yine de atamak için tüm baytları yeni bir diziye kopyalayacağını unutmayın c[]
! ByteBuffer
Yöntemi, belleği boşa harcamayan yakın bir rakip olarak düşünün .
İşte kullanarak güzel bir çözüm Guava 'ler com.google.common.primitives.Bytes
:
byte[] c = Bytes.concat(a, b);
Bu yöntemle ilgili en iyi şey, varargs imzası olmasıdır:
public static byte[] concat(byte[]... arrays)
başka bir deyişle, tek bir yöntem çağrısında rastgele sayıda diziyi birleştirebilirsiniz.
Başka bir olasılık kullanmaktır java.nio.ByteBuffer
.
Gibi bir şey
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();
Dizinin başlayabilmesi için uygun şekilde boyutlandırılması gerektiğine dikkat edin, bu nedenle ayırma satırı gereklidir ( array()
sadece ofset, konum veya sınır dikkate alınmadan destek dizisini döndürdüğü için).
ByteBuffer.allocate(int)
somutlaştırılmış java.nio.HeapByteBuffer
, alt sınıfını döndüren statik bir yöntemdir ByteBuffer
. .put()
Ve .compact()
yöntemler - ve diğer soyut-lık - halledilir.
compact()
Yanlış olduğu için hat kaldırıldı .
bb.flip(); bb.get(result);
yerine çıkararak çözüyorum byte[] result = bb.array();
.
allocate
yöntemin dikkatli bir şekilde okunması aşağıdakileri ortaya çıkarır: "Yeni tamponun konumu sıfır olacak, sınırı kapasitesi olacak, işareti tanımlanmayacak ve öğelerinin her biri sıfırlanacak Bir yedekleme dizisine sahip olacak ve dizi ofseti sıfır olacaktır. " Yani bunun için belirli kod parçası, ByteBuffer
dahili olarak tahsis edilir, bu bir sorun değil.
Başka bir yol bir yardımcı program işlevini kullanmaktır (isterseniz bunu genel bir yardımcı sınıfın statik bir yöntemi yapabilirsiniz):
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;
}
Şöyle çağır:
byte[] a;
byte[] b;
byte[] result = concat(a, b);
Ayrıca 3, 4, 5 dizileri birleştirmek için de çalışır.
Bu şekilde yapmak, okunması ve bakımı çok kolay olan hızlı dizi kod avantajı sağlar.
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'ı tercih ederseniz, her zaman iki byte[]
(veya daha fazla) bir satırda birleştirme olasılığı vardır , örneğin:
byte[] c = ByteBuffer.allocate(a.length+b.length).put(a).put(b).array();
Apache Commons Lang gibi Temiz Kod için üçüncü taraf kitaplıklarını kullanabilir ve aşağıdaki gibi kullanabilirsiniz:
byte[] bytes = ArrayUtils.addAll(a, b);
ArrayUtils.addAll(a, b)
ve byte[] c = Bytes.concat(a, b)
ikincisi daha hızlı.
İki veya birden çok dizi için, bu basit ve temiz yardımcı program yöntemi kullanılabilir:
/**
* 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 içeren iki bayt dizisini birleştiriyorsanız, bu mantık çalışmaz. Apache'den PDFbox gibi üçüncü taraf bir araç kullanmamız gerekiyor:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
mergePdf.addSource(new ByteArrayInputStream(a));
mergePdf.addSource(new ByteArrayInputStream(b));
mergePdf.setDestinationStream(byteArrayOutputStream);
mergePdf.mergeDocuments();
c = byteArrayOutputStream.toByteArray();
Dizilerin boyutlarıyla uğraşmak istemiyorsanız, dize birleştirme sihrini kullanın:
byte[] c = (new String(a, "l1") + new String(b, "l1")).getBytes("l1");
Veya kodunuzda bir yer tanımlayın
// concatenation charset
static final java.nio.charset.Charset cch = java.nio.charset.StandardCharsets.ISO_8859_1;
ve kullan
byte[] c = (new String(a, cch) + new String(b, cch)).getBytes(cch);
Bu, elbette, +
toplama operatörünü kullanarak ikiden fazla dize birleştirmesiyle de çalışır .
Her ikisi de "l1"
ve ISO_8859_1
her karakteri tek bir bayt olarak kodlayan Batı Latin 1 karakter kümesini gösterir. Çok baytlı çeviriler yapılmadığından, dizedeki karakterler baytlarla aynı değerlere sahip olur (yalnızca char
imzasız olduğu gibi her zaman pozitif değerler olarak yorumlanırlar ). En azından Oracle tarafından sağlanan çalışma zamanı için, herhangi bir bayt doğru şekilde "kod çözülecek" ve sonra tekrar "kodlanacaktır".
Dizelerin bayt dizisini ek bellek gerektirerek önemli ölçüde genişlettiğine dikkat edin. Teller de stajyer olabilir ve bu nedenle kolayca çıkartılamaz. Dizeler de değişmezdir, bu nedenle içindeki değerler yok edilemez. Bu nedenle, hassas dizileri bu şekilde birleştirmemeli veya bu yöntemi daha büyük bayt dizileri için kullanmamalısınız. Bu dizi birleştirme yöntemi yaygın bir çözüm olmadığından, ne yaptığınıza dair net bir gösterge vermek de gerekecektir.
Bunu yapmanın yolu bu!
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;
}
Özellikler :
...
sayıda bayt [] ile çağrılmak için varargs ( ) kullanın .System.arraycopy()
yüksek hızda çalışmasını sağlamak için, bu makine Belirli yerel koduyla uygulanmaktadır.int
yeniden kullanarak daha az değişken tahsis edin .i
len
Unutmayın :
Bunu yapmanın en iyi yolu @Jonathan kodunu kopyalamaktır . Sorun, yerel değişken dizilerinden kaynaklanır, çünkü Java, bu veri türü başka bir işleve geçirildiğinde yeni değişkenler oluşturur.
System.arrayCopy
,ByteBuffer
ve - bu yüzden verimli ama okunabilir değil -ByteArrayOutputStream
tüm kaplanmıştır. Burada verilen cevapların 7'den fazla kopyası var. Lütfen daha fazla kopya göndermeyin.