2011-12-01 69 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