如何反复读取同一个 InputStream 对象
如何反復讀取同一個 InputStream 對象
- 方法 1
- 方法 2
- byte 數組與 InputStream 的相互轉化
- byte 數組轉 InputStream
- InputStream轉 byte 數組
 
- 實現反復讀 InputStream
 
??我們知道,每次從 InputStream 對象中讀取數據后,其當前讀取位置的指針就會發生移動。如果在讀取完的某時還想重新從此 InputStream 對象中讀取數據,但此指針已到盡頭,因此無法做到這一點。另外,InputStream 還不支持克隆,這意味著也不能事先備份這個 InputStream 對象。不過,這并不是沒有辦法。
方法 1
??如果使用的 InputStream 對象支持方法 mark,可以聯合方法 reset 來進行 InputStream 對象的讀取重置。方法是,先使用方法 mark 標記一個位置,然后之后在需要重置的時候,使用方法 reset 來將此 InputStream 對象重置到剛才的位置。
??方法 mark 的使用規則如下。當 InputStream 對象調用方法 mark 時,它會在此 InputStream 對象的當前讀取位置做一個標記。不過,它需要提供一個參數,這個參數是一個讀取范圍。在標記后繼續從 InputStream 中讀取數據時,如果讀取到的數據大小超過了這個范圍,則之后調用方法 reset 時將直接拋出異常。可以看出,在此處,這個參數沒有太大的作用,最好設置為大于需要讀取的數據大小,一般設置為在此 InputStream 對象的方法 available 的返回值即可。
??使用模板如下:
// 如果此 inputStream 支持方法 markif (inputStream.markSupported()) {try {inputStream.mark(imageStream.available()); // 在當前位置作標記} catch (IOException ioException) {ioException.printStackTrace(); // TODO:處理異常}// TODO:從此 InputStream 對象中讀取數據try {inputStream.reset(); // 將 inputStream 重置} catch (IOException ioException) {ioException.printStackTrace(); // TODO:處理異常}// TODO:重新開始從此 InputStream 對象中讀取數據try {inputStream.reset(); // 將 inputStream 再次進行重置,以供以后可能進行的再次讀取} catch (IOException ioException) {ioException.printStackTrace(); // TODO:處理異常}} else {// TODO:如果不支持方法 mark,使用其它的辦法 }方法 2
??如果使用的 InputStream 對象不支持方法 mark(比如,FileInputStream 就不支持此方法),可以考慮使用經典的方法,這種方法類似于深克隆的通用方法。可以先將此 InputStream 對象轉化為另一種只讀的獨立的數據類型,然后再用此數據類型不斷生成所需的 InputStream 對象。這種方法有很多,比方說,先將 InputStream 對象轉化為 byte 數組,然后創建一個 InputStream 對象來讀取此 byte 數組。但是,這種方法需要在一開始就從 InputStream 中讀取完全部的數據,這樣就會失去 InputStream 對象惰性讀取的優勢,因此最好使用上面的 方法 1。這里給出借助 byte 數組來完成這一功能的辦法。
byte 數組與 InputStream 的相互轉化
byte 數組轉 InputStream
public static byte[] inputStream2byteArray(InputStream inputStream) throws IOException {return inputStream.readAllBytes(); }InputStream轉 byte 數組
public static InputStream byteArray2InputStream(byte[] bytes) {return new ByteArrayInputStream(bytes); }實現反復讀 InputStream
byte[] bytes = new byte[0]; try {bytes = inputStream2byteArray(inputStream); } catch (IOException ioException) {ioException.printStackTrace(); // TODO:處理異常 }// TODO:當需要 InputStream 時,可以直接獲得一個新的 InputStream。 var needInputStream = byteArray2InputStream(bytes);// TODO:反復獲得 InputStream var needInputStream2 = byteArray2InputStream(bytes);// TODO:...總結
以上是生活随笔為你收集整理的如何反复读取同一个 InputStream 对象的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Git、TortoiseGit、GitH
- 下一篇: 如何联网获取北京时间
