Java IO: InputStream

喝水會長肉發表於2021-11-27

InputStream類是Java IO API中所有輸入流的基類。InputStream子類包括FileInputStream,BufferedInputStream,PushbackInputStream等等。參考Java IO概述這一小節底部的表格,可以瀏覽完整的InputStream子類的列表。


Java InputStream例子

InputStream用於讀取基於位元組的資料,一次讀取一個位元組,這是一個InputStream的例子:

InputStream
&amp
;nbsp
;inputstream
&amp
;nbsp
;
=
&amp
;nbsp
;
new
&amp
;nbsp
;
FileInputStream
(
"c:\\data\\input-text.txt"
)
;


int &amp ;nbsp ;data &amp ;nbsp ; = &amp ;nbsp ;inputstream . read ( ) ;

while (data &amp ;nbsp ; != &amp ;nbsp ; - 1 ) &amp ;nbsp ; { &amp ;nbsp ;

&amp ;nbsp ;   //do something with data...  
    doSomethingWithData (data ) ; &amp ;nbsp ; &amp ;nbsp ; &amp ;nbsp ;

   data &amp ;nbsp ; = &amp ;nbsp ;inputstream . read ( ) ;

}

inputstream . close ( ) ;

這個例子建立了FileInputStream例項。FileInputStream是InputStream的子類,所以可以把FileInputStream例項賦值給InputStream變數。

注意:為了清晰,程式碼忽略了一些必要的異常處理。想了解更多異常處理的資訊,請參考Java IO異常處理。

從Java7開始,你可以使用“try-with-resource”結構確保InputStream在結束使用之後關閉,連結指向了一篇關於“try-with-resource”是如何工作的文章,這裡只是一個簡單的例子:


try
(
&amp
;nbsp
;InputStream
&amp
;nbsp
;inputstream
&amp
;nbsp
;
=
&amp
;nbsp
;
new
&amp
;nbsp
;
FileInputStream
(
"file.txt"
)
&amp
;nbsp
;
)
&amp
;nbsp
;
{


   int &amp ;nbsp ;data &amp ;nbsp ; = &amp ;nbsp ;inputstream . read ( ) ;

    while (data &amp ;nbsp ; != &amp ;nbsp ; - 1 ) {

       System .out . print ( (char ) &amp ;nbsp ;data ) ;

       data &amp ;nbsp ; = &amp ;nbsp ;inputstream . read ( ) ;

    }

}

當執行執行緒退出try語句塊的時候,InputStream變數會被關閉。

read()

read()方法返回從InputStream流內讀取到的一個位元組內容(譯者注:0~255),例子如下:

1 int  data = inputstream.read();

你可以把返回的int型別轉化成char型別:

char aChar = (char) data;

InputStream的子類可能會包含read()方法的替代方法。比如,DataInputStream允許你利用readBoolean(),readDouble()等方法讀取Java基本型別變數int,long,float,double和boolean。

流末尾

如果read()方法返回-1,意味著程式已經讀到了流的末尾,此時流內已經沒有多餘的資料可供讀取了。-1是一個int型別,不是byte或者char型別,這是不一樣的。

當達到流末尾時,你就可以關閉流了。

read(byte[])

InputStream包含了2個從InputStream中讀取資料並將資料儲存到緩衝陣列中的read()方法,他們分別是:

  • int read(byte b[])

  • int read(byte b[], int offset, int length)

一次性讀取一個位元組陣列的方式,比一次性讀取一個位元組的方式快的多,所以,儘可能使用這兩個方法代替read()方法。

read(byte[])方法會嘗試讀取與給定位元組陣列容量一樣大的位元組數,返回值說明了已經讀取過的位元組數。如果InputStream內可讀的資料不足以填滿位元組陣列,則陣列剩餘部分將保留引數傳入時的原始資料,記得檢查有多少資料實際被寫入到了位元組陣列中,以防讀取無效資料。

read(byte, int offset, int length)方法同樣將資料讀取到位元組陣列中,不同的是,該方法從陣列的offset位置開始,並且最多將length個位元組寫入到陣列中。同樣地,read(byte, int offset, int length)方法返回一個int變數,告訴你已經有多少位元組已經被寫入到位元組陣列中,所以請記得在讀取資料前檢查上一次呼叫read(byte, int offset, int length)的返回值。

這兩個方法都會在讀取到達到流末尾時返回-1。

這是一個使用InputStream的read(byte[])的例子:


//java學習交流:737251827  進入可領取學習資源及對十年開發經驗大佬提問,免費解答!

InputStream &nbsp ;inputstream &nbsp ; = &nbsp ; new &nbsp ; FileInputStream ( "c:\\data\\input-text.txt" ) ;

byte [ ] &nbsp ;data = &nbsp ; new &nbsp ;byte [ 1024 ] ;

int bytesRead &nbsp ; = &nbsp ;inputstream . read (data ) ;

while (bytesRead &nbsp ; != &nbsp ; - 1 ) &nbsp ; {

  doSomethingWithData (data , &nbsp ;bytesRead ) ;

   bytesRead &nbsp ; = &nbsp ;inputstream . read (data ) ;

}

inputstream . close ( ) ;


在程式碼中,首先建立了一個位元組陣列。然後宣告一個叫做bytesRead的儲存每次呼叫read(byte[])返回值的int變數,並且將第一次呼叫read(byte[])得到的返回值賦值給它。

在while迴圈內部,把位元組陣列和已讀取位元組數作為引數傳遞給doSomethingWithData方法然後執行呼叫。在迴圈的末尾,再次將資料寫入到位元組陣列中。

你不需要想象出read(byte, int offset, int length)替代read(byte[])的場景,幾乎可以在使用read(byte, int offset, int length)的任何地方使用read(byte[])。

輸入流和資料來源

一個輸入流往往會和資料來源聯絡起來,比如檔案,網路連線,管道等,更多細節已經在Java IO概述文章中介紹過了。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010294/viewspace-2844429/,如需轉載,請註明出處,否則將追究法律責任。

相關文章