2010-04-26 20 views
20

Java'da bir OutputStream'den (bu veriyi o akışa kendim veriyorum) bir ByteBuffer'a koymalıyım. Basit bir şekilde nasıl yapılır?Bir OutputStream'den bir ByteBuffer'a veri nasıl eklenir?

+1

Genel olarak, doğrudan bir çıkış akışından okuyamazsınız. Verileri kendiniz doldurursanız, neden onu ByteBuffer'a da yerleştiremezsiniz? –

+0

Doğrudan OutputStream formunu devralan ve doğrudan okunmasını mümkün kılan bir sınıf oluşturursanız, dolaylı olarak ve dolaylı olarak da okumak mümkündür. Verileri kendim doldurmadım, bazı çerçeve yaptım (ve çerçevenin nedenine değinmek istemiyorum). Diğer yorumumu ve cevaplarımı da gör. – drasto

cevap

30

ByteArrayOutputStream yazabilir ve buna yazabilir ve toByteArray() kullanarak içeriğini byte[] olarak ayıklayabilirsiniz. Sonra ByteBuffer.wrap(byte []), çıkış bayt dizisinin içeriğiyle bir ByteBuffer oluşturur.

+0

Bu, yorumunuzu okumadan hemen önce yaptığım şey. Bu yüzden şunu onaylayabilirim :)) – drasto

+5

Ne yazık ki, ByteArrayOutputStream # toByteArray() 'temeldeki bayt dizisinin bir kopyasını oluşturur, bu yüzden bu reçete basitken, istediğimiz kadar verimli olmaz. Ancak, ByteBuffer'ın kapasite olarak sabitlendiğinden, bir "OutputStream" aracılığıyla bir "ByteBuffer" içine rasgele miktarda veri yazma isteği uzlaştırılamaz. – seh

+0

@seh Bu şekilde olmak zorunda değil - cevabımı gör. – mark

1

OutputStream yerine PipedOutputStream kullanmayı deneyin. Daha sonra PipedOutputStream'den geri veri okumak için bir PipedInputStream bağlayabilirsiniz.

+0

Güzel görünüyor. Benzer bir düşünce, newInputStream yöntemini çağırarak ByteArrayOutputStream ile yapılabilir. Bununla birlikte, ByteArrayOutputStream'i doğrudan ByteBuffer'a yedekleyen diziyi sarmalamak için daha doğru bir çözüm var. Yaptığım şey buydu. – drasto

18

@ DJClayworth'un yanıtının daha verimli bir varyantı var.

zamanda @seh doğru fark, ByteArrayOutputStream.toByteArray() verimsiz olabilir destek byte[] nesne, bir kopyasını döndürür. Ancak, byte[] desteğinin yanı sıra baytların sayısı da ByteArrayOutputStream sınıfının korumalı üyeleridir. Dolayısıyla, doğrudan onlara açığa ByteArrayOutputStream kendi varyantı oluşturabilirsiniz: Bu sınıfını kullanma

public class MyByteArrayOutputStream extends ByteArrayOutputStream { 
    public MyByteArrayOutputStream() { 
    } 

    public MyByteArrayOutputStream(int size) { 
    super(size); 
    } 

    public int getCount() { 
    return count; 
    } 

    public byte[] getBuf() { 
    return buf; 
    } 
} 

kolaydır:

Sonuç olarak
MyByteArrayOutputStream out = new MyByteArrayOutputStream(); 
fillTheOutputStream(out); 
return new ByteArrayInputStream(out.getBuf(), 0, out.getCount()); 

kez tüm çıkış aynı tampon kullanılır yazılır Bir giriş akışının temeli olarak.

+3

İyi nokta, @mark. Java projelerimin çoğunda böyle bir sınıf var, genellikle 'PromiscuousByteArrayOutputStream' adlı paket özel sınıfı olarak kısıtlanmış. İsim kasten uzun ve uğursuz. ByteArrayOutputStream.size(), sayımı döndürdüğünden, – seh

+1

getCount() gerekli değildir. –

4

Yukarıda belirtilen yanıtlar sorununuzu çözse de, bunların hiçbiri NIO'dan beklediğiniz kadar verimli değildir. ByteArrayOutputStream veya MyByteArrayOutputStream önce verileri bir Java yığın belleğine yazar ve daha sonra performansı büyük ölçüde etkileyen ByteBuffer'a kopyalayın.

Etkin bir uygulama, ByteBufferOutputStream sınıfını kendiniz yazıyor olabilir. Aslında yapmak oldukça kolay. Sadece bir write() yöntemi sağlamanız gerekir. ByteBufferInputStream için bu bağlantıya bakın.

+0

, yeni bir ByteBuffer almak için yeni bir dizi ayırmak yerine, mevcut bir ByteBuffer'ı (ve onun altında yatan diziyi) yeniden kullanmak gerektiğinden, bu cevabın daha kabul edilebilir olduğuna inanıyorum. – Ambling

İlgili konular