摘要:關閉此輸入流并釋放與該流關聯的所有系統資源。在此輸入流中標記當前的位置。從輸入流中讀取一定數量的字節,并將其存儲在緩沖區數組中。將此流重新定位到最后一次對此輸入流調用方法時的位置。
一、寫在前面
在Java中流的一系列操作,可能會感到既熟悉又陌生。熟悉是因為很基礎且出鏡率很高,陌生對大多數程序員平時工作中很少寫相關的代碼。
~~ 我是很少寫~~
回歸正題,本章我不不是探討流,主要來說下造成‘標題’問題的原因。
問題很簡單,稍微看下源碼或者debug下就可以找到問題所在,這是一些細節問題,既然出現了在此做下記錄,給自己一個警惕。
二、場景引入今天微信上突然收到前同事一段這樣的問題描述
在讀取文件時如果文件為空、導致進入while死循環,
并附上一段代碼。
/** * 將文件數據流寫入到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; } } } }
咋一看這段代碼也沒啥問題!~是不是~
三、解決思路我們一點點的來分析下
首先陷入while死循環的條件bInStream.read(buffer)) != -1
while ((r = bInStream.read(buffer)) != -1) { outputStream.write(buffer, 0, r); }
看下源碼中的描述,
/** * Reads up tolen
bytes of data from this input stream * into an array of bytes. Iflen
is not zero, the method * blocks until some input is available; otherwise, no * bytes are read and0
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 arrayb
* @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 Ifb
isnull
. * @exception IndexOutOfBoundsException Ifoff
is negative, *len
is negative, orlen
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[]數組的len為0則不做任何操作直接返回0。
看到這問題基本就可以定位了,在看代碼中byte[]的定義。
byte[] buffer = new byte[inputStream.available()];
看到這小伙們就笑了inputStream.available(),你讀的是一個空文件可不是為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(); }
描述的很清楚,返回此輸入流下一個方法調用可以不受阻塞地從此輸入流讀取(或跳過)的估計字節數。
說到這基本就反應過來,再說就有點啰嗦了。
四、總結像這種問題其實和技術和能力沒多大關系、主要是細心和經驗。其實定義一個程序員的牛逼與否在于他踩過的坑是否足夠多。
既然說到這那就順便溫故下InputStream的幾個方法吧!
int available() : 返回此輸入流下一個方法調用可以不受阻塞地從此輸入流讀?。ɑ蛱^)的估計字節數。void close() : 關閉此輸入流并釋放與該流關聯的所有系統資源。
void mark(int readlimit): 在此輸入流中標記當前的位置。
boolean markSupported() : 測試此輸入流是否支持 mark 和 reset 方法。
abstract int read() : 測試此輸入流是否支持 mark 和 reset 方法。
int read(byte[] b) : 從輸入流中讀取一定數量的字節,并將其存儲在緩沖區數組 b 中。
int read(byte[] b, int off, int len) : 將輸入流中最多 len 個數據字節讀入 byte 數組。
void reset() : 將此流重新定位到最后一次對此輸入流調用 mark 方法時的位置。
long skip(long n) : 跳過和丟棄此輸入流中數據的 n 個字節。
以次簡單的問題來對InputStream 溫故。
如有分析的錯誤的地方、歡迎指正
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/74640.html
摘要:不同類型的流入,往往對應于不同類型的流數據。所以通常會將字節緩存到一定數量后再發送。如果是,則將兩個標記都拋棄并且將之前的內容作為一行返回。因此二者陷入死鎖。因此推出了和類。 前言 最近在重拾Java網絡編程,想要了解一些JAVA語言基本的實現,這里記錄一下學習的過程。 閱讀之前,你需要知道 網絡節點(node):位于網絡上的互相連通的設備,通常為計算機,也可以是打印機,網橋,路由器等...
摘要:不建議對這兩個對象嘗試使用單個線程,因為這樣可能會造成該線程死鎖。構造函數創建尚未連接到管道輸入流的管道輸出流。通常,數據由某個線程從對象讀取,并由其他線程將其寫入到相應的。 管道流 管道流的主要作用是可以進行兩個線程間的通訊,分為管道輸出流(PipedOutputStream)、管道輸入流(PipedInputStream),如果想要進行管道輸出,則必須要把輸出流連在輸入流之上,在...
小編寫這篇文章的主要目的,是用來給大家做一個介紹的,介紹關于在Python中。流程控制條件一些問題,另外還有如何進行for循環呢?下面小編給大家詳細的進行闡述一下。1、if條件選擇 #coding:utf-8 num=23 ifnum>2: print("dayu") ifnum<2: print("xiaoyu") ...
摘要:遇到的問題在用通信傳輸一個文件以及其他的非文件的時候總是傳到服務端的文件出錯,后來發現是在用字符流和字節流在讀取各種文件上的差別所導致的讀取文件的方式字節流讀取和,其讀取的方式按字節讀取,這個常用于讀取原始數據。 遇到的問題 在用socket通信傳輸一個pdf文件以及其他的非txt文件的時候總是傳到服務端的文件出錯,后來發現是在用字符流和字節流在讀取各種文件上的差別所導致的 java讀...
小編寫這篇文章的主要目的,主要是給大家做一個比較詳細的解答,因為很多人在使用python的時候,往往會遇到各種各樣的問題,比如if控制語句和for循環這些內容,不能夠合理地進行運用,那么,具體要怎么使用呢?下面小編就給大家詳細解答下?! ?、if條件選擇 #coding:utf-8 num=23 ifnum>2: print("dayu") i...
閱讀 3944·2021-11-16 11:50
閱讀 938·2021-11-11 16:55
閱讀 3664·2021-10-26 09:51
閱讀 868·2021-09-22 15:03
閱讀 3428·2019-08-30 15:54
閱讀 3268·2019-08-30 15:54
閱讀 2479·2019-08-30 14:04
閱讀 924·2019-08-30 13:53