国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java INPUTSTREAM如何實(shí)現(xiàn)重復(fù)使用

瀏覽:6日期:2022-08-22 17:55:22

引語(yǔ):

之前做項(xiàng)目的時(shí)候遇到一個(gè)問(wèn)題,就是從網(wǎng)絡(luò)中讀取的圖片要上傳到oss,而且要對(duì)圖片進(jìn)行裁剪和壓縮,其中上傳和裁剪都要使用到圖片的inputStream,

又因?yàn)閕nputstream不能重復(fù)讀,導(dǎo)致裁剪是成功的,而上傳是失敗的.我們今天就提供兩種方法來(lái)解決,inputStream不能重復(fù)讀的問(wèn)題.

問(wèn)題分析:

inputStream的內(nèi)部有個(gè)pos指針,當(dāng)讀取的時(shí)候指針會(huì)不斷的移動(dòng),當(dāng)移動(dòng)到末尾的時(shí)候,就無(wú)法再次讀取了.

我們寫個(gè)簡(jiǎn)單的例子來(lái)看下:

String text = '測(cè)試inputStream內(nèi)容';InputStream inputStream = new ByteArrayInputStream(text.getBytes());byte[] readArray = new byte[inputStream.available()];int readCount1 = inputStream.read(readArray);System.out.println('讀取了' + readCount1 + '個(gè)字節(jié)');

byte[] readArray2 = new byte[inputStream.available()];int readCount2 = inputStream.read(readArray2);System.out.println('讀取了' + readCount2 + '個(gè)字節(jié)');/*** 執(zhí)行結(jié)果是* 讀取了23個(gè)字節(jié)* 讀取了-1個(gè)字節(jié)*/

從執(zhí)行結(jié)果可以看出確實(shí)inputstream的設(shè)計(jì)是只能讀取一次.

注意: 這里稍微提一下inputStream.available()這個(gè)方法,本地的文件可以直接知道文件的大小,但是如果是網(wǎng)絡(luò)中的數(shù)據(jù),這個(gè)方法最好不要用,因?yàn)閭鬏數(shù)臅r(shí)候不是連續(xù)的,數(shù)據(jù)的大小會(huì)讀取不準(zhǔn)

問(wèn)題解決:

那么我們實(shí)際項(xiàng)目中應(yīng)該怎么解決呢?總不能就真的只使用一次inputSteam吧.我們來(lái)看解決方法:

方法一:

使用ByteArrayOutputStream來(lái)緩存字節(jié),然后每次讀取從緩存的ByteArrayOutputStream中拿取.

很自然的想到把inputStream的緩存起來(lái)(當(dāng)然不一定說(shuō)是要放在ByteArrayOutputStream,其他的方式也可以,都是緩存起來(lái)的思路,實(shí)現(xiàn)方式有很多種,這種比較方便)

String text = '測(cè)試inputStream內(nèi)容';InputStream rawInputStream = new ByteArrayInputStream(text.getBytes());ByteArrayOutputStream outputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;while ((len = rawInputStream.read(buffer)) > -1) {outputStream.write(buffer, 0, len);}outputStream.flush();InputStream in1 = new ByteArrayInputStream(outputStream.toByteArray());InputStream in2 = new ByteArrayInputStream(outputStream.toByteArray());int readCount1 = in1.read(buffer);int readCount2 = in2.read(buffer);System.out.println('讀取了' + readCount1 + '個(gè)字節(jié)');System.out.println('讀取了' + readCount2 + '個(gè)字節(jié)');/*** 執(zhí)行結(jié)果是* 讀取了23個(gè)字節(jié)* 讀取了23個(gè)字節(jié)*

這里是先將inputStream的數(shù)據(jù)讀取到output中,然后要反復(fù)使用inputStream中的內(nèi)容的時(shí)候,我們將output中的數(shù)據(jù)取出(很神奇的設(shè)定,output可以反復(fù)取,input只能讀一次)

方法二:

其實(shí)inputStream中有操作指針的方法,mark和reset,聽名字就知道是標(biāo)記和重置.在使用inputSteam前我們標(biāo)記下inputStream指針的位置,讀取完之后,重置,然后就可以反復(fù)使用了.我們看代碼:

String text = '測(cè)試inputStream內(nèi)容';InputStream rawInputStream = new ByteArrayInputStream(text.getBytes());byte[] readArray = new byte[1024];rawInputStream.mark(0);int readCount1 = rawInputStream.read(readArray);rawInputStream.reset();int readCount2 = rawInputStream.read(readArray);System.out.println('讀取了' + readCount1 + '個(gè)字節(jié)');System.out.println('讀取了' + readCount2 + '個(gè)字節(jié)');

總結(jié):

1.inputStream只能讀取一次,也就是說(shuō)只能調(diào)用read()或者其他的帶參數(shù)的read()方法一次,在下次調(diào)用讀取出來(lái)是-1,做項(xiàng)目的時(shí)候不要忘記這一點(diǎn)了,可能會(huì)導(dǎo)致有些坑出現(xiàn);

2.可以使用緩存或者mark/reset方法來(lái)重復(fù)使用inputStream,這里要注意的是如果inputStream如果內(nèi)容很多,緩存不是一個(gè)好辦法,因?yàn)樵谑褂猛曛皶?huì)占用大量的內(nèi)存(我遇到過(guò)這樣的,上傳很多圖片然后還有緩存,導(dǎo)致內(nèi)存不夠就一直fullGC,然后cpu先爆了);

3.還有一個(gè)小點(diǎn)就是別忘了關(guān)閉使用完的inputStream/outputSteam.

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 久久国产亚洲欧美日韩精品 | 免费一级视频在线播放 | yellow中文字幕久久网 | 久久99热精品免费观看k影院 | ppypp日本欧美一区二区 | 爆操巨乳美女 | 免费观看视频成人国产 | 成人免费一级毛片在线播放视频 | 免费一级毛片在线播放放视频 | 国产精品久久九九 | 男人精品一线视频在线观看 | 嫩模大尺度人体福利视频 | 特黄特色大片免费播放路01 | 亚洲区精品 | 欧美另类精品 | 欧美a在线视频 | 在线视频 自拍 | 99久久精品免费国产一区二区三区 | 国产精品三级在线观看 | 手机福利片 | 久久亚洲国产精品五月天 | 国产精品极品美女自在线看免费一区二区 | 黑人巨大videos极度另类 | 免费一区二区三区四区五区 | 国产韩国精品一区二区三区久久 | 久久久久久久久久久久久久久久久 | 国产高清精品自在久久 | 美女扒开腿让男人桶 | 欧美日韩 国产区 在线观看 | 激情欧美一区二区三区 | 丝袜美腿在线不卡视频播放 | 国产精品成人久久久 | 中文字幕一二三四区2021 | 欧美一级在线观看播放 | 欧美成a人片在线观看久 | 免费一级欧美片在线观看 | 亚洲a级在线观看 | 一本久综合久久爱 | 日韩欧美一区二区三区免费观看 | 五月色婷婷综合开心网亚 | 国产三级在线播放线 |