13. Java IO: InputStream

想要查看此教程的目錄請點擊:Java IO教程目錄貼地址


InputStream是Java IO中所有輸入流的基類。它的子類包括FileInputStream,BufferedInputStream和PushbackInputStream等。想要查看所有詳細的列表,請看“Java IO Overview”章節(jié)。

InputStreams and Sources

InputStream經常被用來連接一些數(shù)據(jù)源,例如文件,網絡連接,管道等等。查看更詳細的信息參考“Java IO Overview”章節(jié)

InputStream例子

它用來讀取字節(jié)數(shù)據(jù),每次讀取一個字節(jié)。下面是一個相關例子:

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

int data = inputstream.read();
while(data != -1) {
  //do something with data...
  doSomethingWithData(data);

  data = inputstream.read();
}
inputstream.close();

這個例子中創(chuàng)建了一個FileInputStream實例。FileInputStream是InputStream的子類所以它可以InputStream類型的變量。
注意:為了代碼清晰,這里并沒有考慮處理異常的情況。想學習更多可以看“Java IO Exception Handling”

Java7開始,你可以用try-with-resources去確保InputStream在使用后可以關閉。具體的用法可以參考上面Java異常處理的文章,但是這里有一個例子:

try( InputStream inputstream = new FileInputStream("file.txt") ) {

    int data = inputstream.read();
    while(data != -1){
        System.out.print((char) data);
        data = inputstream.read();
    }
}

只要線程已經執(zhí)行出try代碼塊,inputstream就會被關閉。

read()

InputStream的read()方法返回一個int類型的值,這個值是每次讀取的字節(jié)的值。下面是一個相關的例子:

int data = inputstream.read();

你也可以把int值強轉成為一個char類型的:

char aChar = (char) data;

InputStream的子類有可能擴展了read()方法。例如,DataInputStream允許讀取java基本類型,像int、long、float、double、boolean等等。當然這些有相應的方法,readBoolean(),readDouble()等等。

Stream的結束

如果read()方法返回 -1,就說明流到已經全部讀取完畢。這里的 -1 是int類型的,不是byte或short。這里是有些不同的!
當流去讀完畢的時候,你可以關閉它了

read(byte[])

InputStream有兩個read()方法,參數(shù)是一個字節(jié)數(shù)組。這些方法是:

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

每次讀取一個字節(jié)數(shù)組顯然要比每次讀取一個字節(jié)要快的多,所以只要有可能,你可以使用這類的方法來替代read()方法。

read(byte[])方法會讀取所有數(shù)據(jù)到數(shù)組中。它會返回一個int值,來告訴實際讀取的字節(jié)數(shù)。萬一實際讀取的字節(jié)數(shù)要比提供的字節(jié)少,那么字節(jié)數(shù)組的其余部分將包含與讀取開始之前所做的相同的數(shù)據(jù)。要記住去檢查返回的int值,看實際取得的字節(jié)數(shù)有多少。
read(byte[], int offset, int length)方法也是讀數(shù)組到數(shù)組中,但是可以根據(jù)參數(shù)來規(guī)定開始的偏移量和一共讀取多少長度。返回值和read(byte[])方法的含義相同。

兩個方法相同的地方都是如果返回值是 -1 ,代表讀取結束。

下面的例子為如何使用InputStream的read(byte[])方法:

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

byte[] data      = new byte[1024];
int    bytesRead = inputstream.read(data);

while(bytesRead != -1) {
  doSomethingWithData(data, bytesRead);

  bytesRead = inputstream.read(data);
}
inputstream.close();

首先,上面代碼創(chuàng)建了一個字節(jié)數(shù)組。然后創(chuàng)建了一個叫bytesRead的int類型變量,去接受每次調用read(byte[])方法的返回值。
在循環(huán)里,doSomethingWithData()方法被循環(huán)調用,傳遞進去讀了多少字節(jié)和字節(jié)數(shù)組。在循環(huán)的最后把數(shù)據(jù)重新讀到數(shù)組一遍。

不用花太多精力放在研究怎么樣使用read(byte[], int offset, int length)方法來替換read(byte[])。你完全可以在任何時候用read(byte[], int offset, int length)替換掉read(byte[])方法。

mark()和reset()

InputStream類中有兩個方法mark()和reset(),但是它的子類不一定有支持(或者說子類有沒有重寫此方法)。

如果一個InputStream的子類支持這兩個方法,子類會重寫markSupported()方法并返回 true。相反的,如果返回false,則子類不支持這兩個方法。

mark()方法在InputStream設置一個內部的標記,標記在流中哪個數(shù)據(jù)到目前為止已經被讀取。使用InputStream的代碼,可以根據(jù)這個標記位來繼續(xù)讀取數(shù)據(jù)。

在讀取流的過程匯總,如果想退回到標記的那點上,可以調用reset()方法。然后InputStream退回到標記位上,開始從這個位置開始返回數(shù)據(jù)。這當然會導致多次返回一些數(shù)據(jù)

當實現(xiàn)一個解析器時,會經常用到這兩個方法。解析器讀取一個InputStream時會提前讀,如果解析器沒有找到它想要的,他可能需要回退并且將已讀數(shù)據(jù)和其他的數(shù)據(jù)進行匹配。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • tags:io categories:總結 date: 2017-03-28 22:49:50 不僅僅在JAVA領...
    行徑行閱讀 2,299評論 0 3
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,638評論 18 399
  • 在經過一次沒有準備的面試后,發(fā)現(xiàn)自己雖然寫了兩年的android代碼,基礎知識卻忘的差不多了。這是程序員的大忌,沒...
    猿來如癡閱讀 3,116評論 3 10
  • 摘要 Java I/O是Java技術體系中非常基礎的部分,它是學習Java NIO的基礎。而深入理解Java NI...
    biakia閱讀 7,778評論 7 81
  • 1.MRC與ARC混編,在seeting prase-> 加上-fno-objc-arc 2.建立cocopods...
    邵瓊閱讀 123評論 0 0

友情鏈接更多精彩內容