2010-04-26 54 views
20

在Java中,我需要將OutputStream中的內容(我自己將數據填充到該流中)放入ByteBuffer中。如何以簡單的方式做到這一點?如何將數據從OutputStream放入ByteBuffer?

+1

通常,您不能直接從輸出流中讀取數據。如果你自己填寫數據,爲什麼你不能將它填充到ByteBuffer中呢? – 2010-04-26 20:28:17

+0

如果您創建繼承了OutputStream形式的類並使其可以直接從中讀取,則可以間接讀取它以及直接讀取原因。我沒有自己填充數據,有的框架(以及我不想觸及的框架代碼)。請參閱我的其他評論和答案。 – drasto 2010-04-30 21:19:13

回答

30

您可以創建ByteArrayOutputStream並寫入,並使用toByteArray()將內容解壓縮爲byte[]。然後ByteBuffer.wrap(byte [])將創建一個ByteBuffer與輸出字節數組的內容。

+0

這正是我在閱讀你的評論之前所做的。所以我可以批准這個工作:)) – drasto 2010-04-26 21:08:28

+5

不幸的是,'ByteArrayOutputStream#toByteArray()'產生了一個底層字節數組的副本,所以儘管這個方法很簡單,但並不像我們想的那樣高效。然而,由於「ByteBuffer」的容量是固定的,因此通過'OutputStream'將任意數量的數據寫入'ByteBuffer'是不可調和的。 – seh 2012-02-02 00:37:21

+0

@seh它不一定要這樣 - 看我的答案。 – mark 2013-03-28 16:05:36

1

嘗試使用PipedOutputStream代替OutputStream。然後,您可以連接一個PipedInputStream以從PipedOutputStream中讀取數據。

+0

看起來很好。 ByteArrayOutputStream通過調用它的newInputStream方法可以做類似的想法。然而,還有更直接的解決方案 - 將ByteArrayOutputStream直接備份到ByteBuffer的數組。這就是我所做的。 – drasto 2010-04-26 21:12:03

18

@ DJClayworth的答案是一個更有效的變體。

作爲@seh正確地注意到,ByteArrayOutputStream.toByteArray()返回背襯byte[]對象,它可能是低效的拷貝。但是,支持byte[]對象以及字節數都是ByteArrayOutputStream類的受保護成員。因此,你可以創建自己的ByteArrayOutputStream的變種直接暴露他們:

public class MyByteArrayOutputStream extends ByteArrayOutputStream { 
    public MyByteArrayOutputStream() { 
    } 

    public MyByteArrayOutputStream(int size) { 
    super(size); 
    } 

    public int getCount() { 
    return count; 
    } 

    public byte[] getBuf() { 
    return buf; 
    } 
} 

使用這個類很簡單:

MyByteArrayOutputStream out = new MyByteArrayOutputStream(); 
fillTheOutputStream(out); 
return new ByteArrayInputStream(out.getBuf(), 0, out.getCount()); 

其結果是,一旦所有的輸出寫入使用相同的緩衝作爲輸入流的基礎。

+3

好點,@mark。我在幾個Java項目中都有這樣的類,通常被限制爲一個名爲'PromiscuousByteArrayOutputStream'的包 - 私有類。這個名字故意漫長而不祥。 – seh 2013-03-28 19:27:20

+1

getCount()不需要,因爲ByteArrayOutputStream.size()返回count。 – 2014-12-24 02:30:37

4

儘管上面提到的答案可以解決您的問題,但它們都不像您期望的那樣高效。 ByteArrayOutputStream或MyByteArrayOutputStream首先將數據寫入Java堆內存,然後將其複製到ByteBuffer,這極大地影響了性能。

一個有效的實現是你自己寫ByteBufferOutputStream類。其實這很容易做到。你必須提供一個write()方法。看到這個鏈接ByteBufferInputStream

+0

,因爲我們可能需要爲OutputStream重用現有的ByteBuffer(及其底層數組),而不是分配新數組來獲得新的ByteBuffer,我相信這個答案更可接受。 – Ambling 2017-06-06 15:55:34