2011-12-01 66 views
1

我无法弄清楚我是否不正确地使用管道流,或者我的问题是否在以下问题的其他地方。使用管道流和jaxb

我有一个对象(称为“ADI”),我编组到一个文件中,如下所示:

final PipedInputStream pipedInputStream = new PipedInputStream(); 
    OutputStream pipedOutputStream = null; 
    pipedOutputStream = new PipedOutputStream(pipedInputStream); 
    log.info("marshalling away"); 
    final OutputStream outputStream = new FileOutputStream(new File(
      "target/test.xml")); 
    m.marshal(adi, outputStream); 
    outputStream.flush(); 
    outputStream.close(); 
    pipedOutputStream.write("test".getBytes()); 
    // m.marshal(adi, pipedOutputStream); 
    pipedOutputStream.flush(); 
    pipedOutputStream.close(); 
    log.info("marshalling done"); 
    return pipedInputStream; 
  • 该代码生成与我期望内容的文件目标/的test.xml(编组对象),验证编组到outputStream中的工作是否正常。
  • 该代码还会生成一个pipedInputStream。如果我遍历从该流中提取的字节并打印它们,它会显示“test”,验证我的输入/输出管道流已正确设置并正常工作的事实。

然而,当我取消

//m.marshal(adi, pipedOutputStream); 

代码挂起永远(永远显示“编组完成的”),而我希望的代码返回一个包含输入流“测试”,然后我的编组对象。

我错过了什么?

感谢

回答

2

我想你想不正确的使用它...

从API(http://docs.oracle.com/javase/6/docs/api/java/io/PipedInputStream.html):

通常情况下,数据是从的PipedInputStream对象读取由一个线程和数据被其他线程写入相应的PipedOutputStream。不建议尝试从单个线程使用这两个对象,因为它可能使线程死锁。

你想要做的是这样的:

log.info("marshalling away"); 
    final OutputStream fileOutputStream = new FileOutputStream(new File(
      "target/test.xml")); 
    m.marshal(adi, fileOutputStream); 
    fileOutputStream.flush(); 
    fileOutputStream.close(); 
    final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
    outputStream.write("test".getBytes()); 
    m.marshal(adi, outputStream); 
    outputStream.flush(); 
    final InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); 
    outputStream.close(); 
    log.info("marshalling done"); 
    return inputStream; 

在这里看到的是如何把一个输出流进输入流更多的例子:http://ostermiller.org/convert_java_outputstream_inputstream.html

有使用临时线程的方式,你可以做类似于您的原始解决方案和管道流。

+0

你说什么是有道理的。因此,让我问一个更一般的问题:如果我的合同是要返回一个包含我的编组对象的InputStream,那我应该怎么做?我坚持把我的对象封装到StringWriter或FileWriter中,然后将生成的字符串或文件转换为inputStream?有没有更有效的资源明智? – double07

+0

对不起,我已经更新了我的答案,包括做什么的示例,以及其他可能性的链接(与您的原始解决方案类似,但使用临时线程来执行PipedOutputStream部分) – MattJenko

+0

谢谢,我做了很多和上面写的一样,只是我通过FileInputStream和FileOutputStream来减少内存需求。你在第一个注释中指出了我的问题:我期待这个代码在一个单独的线程中执行(产生数据,因为它们正在被消耗)没有设置任何多线程环境。感谢您的帮助。 – double07