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