I'm trying to store binary data in JCR, which is created on the fly. My problem is that the only way provided by the JCR API is via an InputStream
:
Session session = request.getResourceResolver().adaptTo(Session.class);
ValueFactory valueFactory = session.getValueFactory();
Binary bin = valueFactory.createBinary(is);
As CQ/Sling is RESTful I can see why this is the case as you usually get a form post or an httprequest to another source, where you always have an InputStream
to use. But in my case I am creating the binary on the fly which usually is represented as an OutputStream
.
OutputStream
directly on the nt:file node, just like a FileOutputStream
?OutpuStream
transformed to an InputStream
?I know the other way is available from the Apache Commons IOUtils.copy()
. I've seen some examples on SO where they just use the ByteArrayOutputStream.toByteArray()
to create an InputStream
. But as the data could get rather large, this is not a good solution. Besides I tried it and somehow the stream was incomplete, so it seems there is a buffer limmit. The next approach was with piped streams, but there I have other problems to which I opened another question: Multiple quotes cause PipedOutputStream/OutputStreamWriter to fail
EDIT:
Removed PipedStream code example as I posted the issue with it in another question. So here I am still just looking for an easy way to create an nt:file where the input is not an InputStream
.
Pipes are good solution here. However, in order to implement them properly, you have to use two threads: first should write data into the PipedOutputStream
and the second should create a Binary
from PipedInputStream
and save it into JCR:
final PipedInputStream pis = new PipedInputStream();
final PipedOutputStream pos = new PipedOutputStream(pis);
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
try {
OutputStreamWriter writer = new OutputStreamWriter(pos);
writer.append("append here some data");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
Binary binary = session.getValueFactory().createBinary(pis);
session.getNode("/content/myNode").setProperty("xyz", binary);
session.save();
The symmetrical solution, in which you handle the JCR in the new thread would be also good.