使用管道流和jaxb

使用管道流和jaxb,jaxb,marshalling,inputstream,outputstream,Jaxb,Marshalling,Inputstream,Outputstream,我无法确定我是否不正确地使用了管道流,或者我的问题是否存在于下面的问题中 我有一个对象(称为“adi”),我将其封送到一个文件中,如下所示: final PipedInputStream pipedInputStream = new PipedInputStream(); OutputStream pipedOutputStream = null; pipedOutputStream = new PipedOutputStream(pipedInputStream); log.i

我无法确定我是否不正确地使用了管道流,或者我的问题是否存在于下面的问题中

我有一个对象(称为“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;
  • 该代码生成一个文件target/test.xml,其中包含我所期望的内容(封送对象),以验证封送到outputStream的工作是否正常
  • 该代码还生成一个pipedInputStream。如果我遍历从该流中提取的字节并打印它们,它将显示“test”,验证输入/输出管道流是否正确设置和工作
然而,当我取消注释时

  //m.marshal(adi, pipedOutputStream);  
代码永远挂起(从不显示“封送完成”),而我希望代码返回一个包含“test”的输入流,后跟我的封送对象

我错过了什么


谢谢

我认为你试图错误地使用它

从API()中:

通常,一个线程从PipedInputStream对象读取数据,另一个线程将数据写入相应的PipedOutStream。不建议尝试从单个线程使用这两个对象,因为这可能会使线程死锁

您要做的是:

  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;
有关如何将输出流转换为输入流的更多示例,请参见此处:


有一种使用临时线程的方法,您可以执行类似于原始解决方案和管道流的操作。

您所说的很有意义。所以,让我问一个更一般的问题:如果我的契约是返回一个包含我的封送对象的InputStream,那么我的方法应该是什么?我是否无法将对象编组为StringWriter或FileWriter,然后将生成的字符串或文件转换为inputStream?在资源方面是否有更有效的方法?对不起,我已经更新了我的答案,包括一个如何做的示例,以及到其他可能性的链接(与您最初的解决方案类似,但使用临时线程来完成PipeDoutpStream部分。谢谢,我所做的与您上面所写的几乎相同,只是我通过FileInputStream和FileOutputStream来减少内存需求。您在第一条评论中明确了我的问题:我希望此代码在一个单独的线程(在数据被消耗时生成数据),而不设置任何多线程环境。感谢您的帮助。正如我所说的,还有另一种选择,即几乎完全按照您所做的操作,但在线程中执行“m.marshal(adi,outputStream)”部分。请参阅我提供的最后一个链接,在“使用管道”下