2015-01-18 16 views
11

Uygulamamda yeni bir modül uygulamak için Iteratees & Numaratörler üzerinde çok fazla okuma yapıyorum.Bir Enumerator'dan bir Java InputStream oluşturma [Array [Byte]

Ben 3. parti Java kütüphanesi ile entegre olduğum bir noktada artık değilim ve bu yöntemle çalışan şaşırıp:

public Email addAttachment(String name, InputStream file) throws IOException { 
    this.attachments.put(name, file); 
    return this; 
} 

Ne benim API var döndü organıdır Enumerator[Array[Byte]] olan bir WS HTTP çağrısı.

Şimdi Array[Bytes] parçalarını işlemek ve bu yöntemde kullanmak için InputStream oluşturmak için bir Iteratee yazmayı merak ediyorum.

(Yan çubuk): java.io.File alan addAttachment yönteminin başka sürümleri vardır, ancak bu işlemde diske yazmamaktan ve akışlarla uğraşmaktan kaçınmak istiyorum.

Böyle bir şey yazmaya başlamak teşebbüs:

Iteratee.foreach[Array[Byte]] { bytes => 
    ??? 
} 

Ancak burada java InputStream etkileşimde nasıl emin değilim. ByteArrayInputStream adında bir şey buldum ancak Array[Byte] yapıcısını alır, bu senaryoda çalışıyorum emin değilim.

Muhtemelen bazı Java yardıma ihtiyacım var!

Yardımlarınız için şimdiden teşekkür ederiz.

+0

Bu zor biridir (netlik için taşıma & kaynak kullanımı istisna dışında bırakılması): Ben Java olurdu, benden daha iyi Scala gibi bir şey işleyebilir eminim. Bence en iyi bahisten, temel sayımla InputStream arayüzünün bir uygulamasını oluşturmaktır. Ve sonra her bir 'okuma 'çağrısında, Enumerator'dan gerekli miktarda bayt tüketin. – Martijn

+0

Bunun dışında, en iyi bahsinizin her şeyi önbelleğe aldığını ve bir ByteArrayInputStream uygulamasına beslediğini düşünüyorum. Sorun şu ki, Enumerator bir basma mekanizması ile bir veri akışıdır ve InputStream bir çekme mekanizmasını kullanır, yani başka bir yerde bir tamponun olması gerekir, aksi takdirde bu işe yaramaz. Şimdilik her şeyi tamponlayabilirsin, ve belki de daha sonra karar verirsin, performans bir darboğaz haline geldiğinde ne yapmalı? Belki kısmi tamponlar yaparsanız, noktayı alırsınız. – Martijn

+2

Bunu henüz test etmedim ancak şu gibi bir şey denedim: 'val consume = gövde | >>> Iteratee.consume . Sanırım bu, ikinci yorumunuzun, ancak arabelleğe alınmadan saf bir şekilde uygulanmasıdır. –

cevap

3

seni takip ediyorum, seni PipedInputStream ve PipedOutputStream çalışmak istediğiniz düşünüyorum:

https://docs.oracle.com/javase/8/docs/api/java/io/PipedInputStream.html

Her zaman çiftler halinde bunları kullanın. Sen şöyle çifti oluşturabilirsiniz:

PipedInputStream in = new PipedInputStream(); //can also specify a buffer size 
PipedOutputStream out = new PipedOutputSream(in); 

API giriş akışı geçirin ve kendi kod yineleme içinde aynalar aracılığıyla ve bayt yazın.

Tek uyarı, ayrı konulara okuma/yazma bilmenizdir. Durumunuzda, yineleme/yazma işleminizi ayrı bir iş parçacığında yapmak muhtemelen iyi.

PipedInputStream in = new PipedInputStream(); //can also specify a buffer size 
PipedOutputStream out = new PipedOutputSream(out); 
new Thread(() -> { 
    // do your looping in here, write to 'out' 
    out.close(); 
}).run(); 
email.addAttachment(in); 
email.send(); 
in.close(); 

İlgili konular