How to write an nt:file programmatically

て烟熏妆下的殇ゞ 提交于 2019-12-21 20:08:03

问题


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.

  1. Is there any other way I overlooked in the JCR API where I could create an OutputStream directly on the nt:file node, just like a FileOutputStream?
  2. If no, is there an easy way to have an 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.


回答1:


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.




回答2:


Have you tried on of the methods described here?

http://ostermiller.org/convert_java_outputstream_inputstream.html

I think the easiest methods would be using an array:

  ByteArrayOutputStream out = new ByteArrayOutputStream(); 
  //alternatively, get the outputstream of your binary file generator
  (...) //put data into out
  InputStream is = new ByteArrayInputStream(out.toByteArray())


来源:https://stackoverflow.com/questions/27170741/how-to-write-an-ntfile-programmatically

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!