double07
double07

Reputation: 2575

Using piped streams and jaxb

I cannot figure out whether I am using piped streams improperly or whether my problem is elsewhere in the issue below.

I have an object (called 'adi') that I marshal into a file as shown below:

  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;

Yet, when I uncomment

  //m.marshal(adi, pipedOutputStream);  

the code hangs forever (never displaying "marshalling done") while I would expect the code to return an input stream containing "test" followed by my marshalled object.

What am I missing?

Thanks

Upvotes: 1

Views: 3428

Answers (1)

MattJenko
MattJenko

Reputation: 1218

I think you're trying to use it incorrectly...

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

Typically, data is read from a PipedInputStream object by one thread and data is written to the corresponding PipedOutputStream by some other thread. Attempting to use both objects from a single thread is not recommended, as it may deadlock the thread.

What you want to do is this:

  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;

See here for more examples of how to turn an output stream into input stream: http://ostermiller.org/convert_java_outputstream_inputstream.html

There is a way using a temporary thread that you can do something similar to your original solution and piped streams.

Upvotes: 3

Related Questions