成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

踩坑歷程 >> InputStream.read(byte[] b) 造成死循環(huán)

he_xd / 2929人閱讀

摘要:關(guān)閉此輸入流并釋放與該流關(guān)聯(lián)的所有系統(tǒng)資源。在此輸入流中標(biāo)記當(dāng)前的位置。從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)數(shù)組中。將此流重新定位到最后一次對(duì)此輸入流調(diào)用方法時(shí)的位置。

一、寫(xiě)在前面

在Java中流的一系列操作,可能會(huì)感到既熟悉又陌生。熟悉是因?yàn)楹芑A(chǔ)且出鏡率很高,陌生對(duì)大多數(shù)程序員平時(shí)工作中很少寫(xiě)相關(guān)的代碼。

~~ 我是很少寫(xiě)~~

回歸正題,本章我不不是探討流,主要來(lái)說(shuō)下造成‘標(biāo)題’問(wèn)題的原因。

問(wèn)題很簡(jiǎn)單,稍微看下源碼或者debug下就可以找到問(wèn)題所在,這是一些細(xì)節(jié)問(wèn)題,既然出現(xiàn)了在此做下記錄,給自己一個(gè)警惕。

二、場(chǎng)景引入

今天微信上突然收到前同事一段這樣的問(wèn)題描述

在讀取文件時(shí)如果文件為空、導(dǎo)致進(jìn)入while死循環(huán),

并附上一段代碼。

/**
     * 將文件數(shù)據(jù)流寫(xiě)入到zip流中
     * 
     * @param fileName
     * @param inputStream
     * @param outputStream
     * @throws IOException
     */
    public static void zipInputStream(String fileName, InputStream inputStream, ZipOutputStream outputStream)
            throws IOException {
        try {
            BufferedInputStream bInStream = new BufferedInputStream(inputStream);
            outputStream.putNextEntry(new ZipEntry(fileName));
            byte[] buffer = new byte[inputStream.available()];
            int r = 0;
            while ((r = bInStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, r);
            }
            outputStream.closeEntry();
        } catch (IOException e) {
            throw e;
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    throw e;
                }
            }
        }
    }

咋一看這段代碼也沒(méi)啥問(wèn)題!~是不是~

三、解決思路

我們一點(diǎn)點(diǎn)的來(lái)分析下

首先陷入while死循環(huán)的條件bInStream.read(buffer)) != -1

while ((r = bInStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, r);
}

看下源碼中的描述,

/**
     * Reads up to len bytes of data from this input stream
     * into an array of bytes. If len is not zero, the method
     * blocks until some input is available; otherwise, no
     * bytes are read and 0 is returned.
     * 

* This method simply performs in.read(b, off, len) * and returns the result. * * @param b the buffer into which the data is read. * @param off the start offset in the destination array b * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because the end of * the stream has been reached. * @exception NullPointerException If b is null. * @exception IndexOutOfBoundsException If off is negative, * len is negative, or len is greater than * b.length - off * @exception IOException if an I/O error occurs. * @see java.io.FilterInputStream#in */ public int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); }

上面描述有這么一段,如果byte[]數(shù)組的len為0則不做任何操作直接返回0。

看到這問(wèn)題基本就可以定位了,在看代碼中byte[]的定義。

byte[] buffer = new byte[inputStream.available()];

看到這小伙們就笑了inputStream.available(),你讀的是一個(gè)空文件可不是為0。

/**
     * Returns an estimate of the number of bytes that can be read (or
     * skipped over) from this input stream without blocking by the next
     * caller of a method for this input stream. The next caller might be
     * the same thread or another thread.  A single read or skip of this
     * many bytes will not block, but may read or skip fewer bytes.
     * 

* This method returns the result of {@link #in in}.available(). * * @return an estimate of the number of bytes that can be read (or skipped * over) from this input stream without blocking. * @exception IOException if an I/O error occurs. */ public int available() throws IOException { return in.available(); }

描述的很清楚,返回此輸入流下一個(gè)方法調(diào)用可以不受阻塞地從此輸入流讀?。ɑ蛱^(guò))的估計(jì)字節(jié)數(shù)。

說(shuō)到這基本就反應(yīng)過(guò)來(lái),再說(shuō)就有點(diǎn)啰嗦了。

四、總結(jié)

像這種問(wèn)題其實(shí)和技術(shù)和能力沒(méi)多大關(guān)系、主要是細(xì)心和經(jīng)驗(yàn)。其實(shí)定義一個(gè)程序員的牛逼與否在于他踩過(guò)的坑是否足夠多。

既然說(shuō)到這那就順便溫故下InputStream的幾個(gè)方法吧!

方法摘要
int available() : 返回此輸入流下一個(gè)方法調(diào)用可以不受阻塞地從此輸入流讀?。ɑ蛱^(guò))的估計(jì)字節(jié)數(shù)。

void close() : 關(guān)閉此輸入流并釋放與該流關(guān)聯(lián)的所有系統(tǒng)資源。

void mark(int readlimit): 在此輸入流中標(biāo)記當(dāng)前的位置。

boolean markSupported() : 測(cè)試此輸入流是否支持 mark 和 reset 方法。

abstract int read() : 測(cè)試此輸入流是否支持 mark 和 reset 方法。

int read(byte[] b) : 從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)數(shù)組 b 中。

int read(byte[] b, int off, int len) : 將輸入流中最多 len 個(gè)數(shù)據(jù)字節(jié)讀入 byte 數(shù)組。

void reset() : 將此流重新定位到最后一次對(duì)此輸入流調(diào)用 mark 方法時(shí)的位置。

long skip(long n) : 跳過(guò)和丟棄此輸入流中數(shù)據(jù)的 n 個(gè)字節(jié)。

以次簡(jiǎn)單的問(wèn)題來(lái)對(duì)InputStream 溫故。

如有分析的錯(cuò)誤的地方、歡迎指正

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74640.html

相關(guān)文章

  • 重拾Java Network Programming(一)IO流

    摘要:不同類(lèi)型的流入,往往對(duì)應(yīng)于不同類(lèi)型的流數(shù)據(jù)。所以通常會(huì)將字節(jié)緩存到一定數(shù)量后再發(fā)送。如果是,則將兩個(gè)標(biāo)記都拋棄并且將之前的內(nèi)容作為一行返回。因此二者陷入死鎖。因此推出了和類(lèi)。 前言 最近在重拾Java網(wǎng)絡(luò)編程,想要了解一些JAVA語(yǔ)言基本的實(shí)現(xiàn),這里記錄一下學(xué)習(xí)的過(guò)程。 閱讀之前,你需要知道 網(wǎng)絡(luò)節(jié)點(diǎn)(node):位于網(wǎng)絡(luò)上的互相連通的設(shè)備,通常為計(jì)算機(jī),也可以是打印機(jī),網(wǎng)橋,路由器等...

    Lycheeee 評(píng)論0 收藏0
  • Java IO學(xué)習(xí)五

    摘要:不建議對(duì)這兩個(gè)對(duì)象嘗試使用單個(gè)線程,因?yàn)檫@樣可能會(huì)造成該線程死鎖。構(gòu)造函數(shù)創(chuàng)建尚未連接到管道輸入流的管道輸出流。通常,數(shù)據(jù)由某個(gè)線程從對(duì)象讀取,并由其他線程將其寫(xiě)入到相應(yīng)的。 管道流 管道流的主要作用是可以進(jìn)行兩個(gè)線程間的通訊,分為管道輸出流(PipedOutputStream)、管道輸入流(PipedInputStream),如果想要進(jìn)行管道輸出,則必須要把輸出流連在輸入流之上,在...

    gaomysion 評(píng)論0 收藏0
  • Python流程控制if條件選擇與for循環(huán)

      小編寫(xiě)這篇文章的主要目的,是用來(lái)給大家做一個(gè)介紹的,介紹關(guān)于在Python中。流程控制條件一些問(wèn)題,另外還有如何進(jìn)行for循環(huán)呢?下面小編給大家詳細(xì)的進(jìn)行闡述一下。1、if條件選擇   #coding:utf-8   num=23   ifnum>2:   print("dayu")   ifnum<2:   print("xiaoyu") ...

    89542767 評(píng)論0 收藏0
  • 關(guān)于java用字節(jié)流和字符流讀取文件的各種情況

    摘要:遇到的問(wèn)題在用通信傳輸一個(gè)文件以及其他的非文件的時(shí)候總是傳到服務(wù)端的文件出錯(cuò),后來(lái)發(fā)現(xiàn)是在用字符流和字節(jié)流在讀取各種文件上的差別所導(dǎo)致的讀取文件的方式字節(jié)流讀取和,其讀取的方式按字節(jié)讀取,這個(gè)常用于讀取原始數(shù)據(jù)。 遇到的問(wèn)題 在用socket通信傳輸一個(gè)pdf文件以及其他的非txt文件的時(shí)候總是傳到服務(wù)端的文件出錯(cuò),后來(lái)發(fā)現(xiàn)是在用字符流和字節(jié)流在讀取各種文件上的差別所導(dǎo)致的 java讀...

    tommego 評(píng)論0 收藏0
  • 怎么使用python控制if語(yǔ)句和for循環(huán)

      小編寫(xiě)這篇文章的主要目的,主要是給大家做一個(gè)比較詳細(xì)的解答,因?yàn)楹芏嗳嗽谑褂胮ython的時(shí)候,往往會(huì)遇到各種各樣的問(wèn)題,比如if控制語(yǔ)句和for循環(huán)這些內(nèi)容,不能夠合理地進(jìn)行運(yùn)用,那么,具體要怎么使用呢?下面小編就給大家詳細(xì)解答下?! ?、if條件選擇 #coding:utf-8   num=23   ifnum&gt;2:   print("dayu")   i...

    89542767 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<