如何以编程方式编写nt:文件

时间:2014-11-27 12:23:16

标签: cq5 jcr aem

我试图将二进制数据存储在即时创建的JCR中。我的问题是JCR API提供的唯一方法是通过InputStream

Session session = request.getResourceResolver().adaptTo(Session.class);
ValueFactory valueFactory = session.getValueFactory();
Binary bin = valueFactory.createBinary(is);

由于CQ / Sling是RESTful,我可以看到为什么会出现这种情况,因为您通常会将表单帖子或httprequest发送到其他来源,您始终可以使用InputStream。但在我的情况下,我正在创建动态二进制文件,通常表示为OutputStream

  1. 我是否在JCR API中忽略了其他任何方法,我可以直接在nt:file节点上创建OutputStream,就像FileOutputStream一样?
  2. 如果不是,是否可以轻松地将OutpuStream转换为InputStream
  3. 我知道另一种方式可以从Apache Commons IOUtils.copy()获得。我在SO上看到了一些示例,他们只使用ByteArrayOutputStream.toByteArray()来创建InputStream。但由于数据可能会变得很大,这不是一个好的解决方案。除了我尝试了它并且不知何故流不完整,所以似乎有缓冲区限制。下一个方法是使用管道流,但在那里我还有其他问题,我打开了另一个问题:Multiple quotes cause PipedOutputStream/OutputStreamWriter to fail

    编辑: 删除了PipedStream代码示例,因为我在另一个问题中发布了它的问题。所以在这里我仍然只是在寻找一种简单的方法来创建一个输入不是InputStream的nt:文件。

2 个答案:

答案 0 :(得分:4)

管道是很好的解决方案。但是,为了正确实现它们,您必须使用两个线程:首先应将数据写入PipedOutputStream,第二个应从Binary创建PipedInputStream并将其保存到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();

在新线程中处理JCR的对称解决方案也不错。

答案 1 :(得分:0)

您是否尝试过此处描述的方法?

http://ostermiller.org/convert_java_outputstream_inputstream.html

我认为最简单的方法是使用数组:

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