Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a Java InputStream from an Enumerator[Array[Byte]]

I've been reading up a lot on Iteratees & Enumerators in order to implement a new module in my application.

I'm now at a point where I'm integrating with a 3rd party Java library, and am stuck at working with this method:

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

What I have in my API is the body returned from a WS HTTP call that is an Enumerator[Array[Byte]].

I am wondering now how to write an Iteratee that would process the chunks of Array[Bytes] and create an InputStream to use in this method.

(Side bar): There are other versions of the addAttachment method that take java.io.File however I want to avoid writing to the disk in this operation, and would rather deal with streams.

I attempted to start by writing something like this:

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

However I'm not sure how to interact with the java InputStream here. I found something called a ByteArrayInputStream however that takes the entire Array[Byte] in its constructor, which I'm not sure would work in this scenario as I'm working with chunks ?

I probably need some Java help here!

Thanks for any help in advance.

like image 817
goralph Avatar asked Jan 18 '15 14:01

goralph


1 Answers

If I'm following you, I think you want to work with PipedInputStream and PipedOutputStream:

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

You always use them in pairs. You can construct the pair like so:

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

Pass the input stream to the API, and in your own code iterate through your chucks and write your bytes.

The only caveat is that you need to read/write in separate threads. In your case, its probably good to do your iterating / writing in a separate thread. I'm sure you can handle it in Scala better than me, in Java it would be something like:

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();

(Leaving out exception handling & resource handling for clarity)

like image 70
romacafe Avatar answered Sep 30 '22 13:09

romacafe