想要查看此教程的目錄請點擊:Java IO教程目錄貼地址
InputStream是Java IO中所有輸入流的基類握巢。它的子類包括FileInputStream,BufferedInputStream和PushbackInputStream等破衔。想要查看所有詳細的列表,請看“Java IO Overview”章節(jié)叹卷。
InputStreams and Sources
InputStream經(jīng)常被用來連接一些數(shù)據(jù)源抚太,例如文件,網(wǎng)絡(luò)連接营曼,管道等等乒验。查看更詳細的信息參考“Java IO Overview”章節(jié)
InputStream例子
它用來讀取字節(jié)數(shù)據(jù),每次讀取一個字節(jié)溶推。下面是一個相關(guān)例子:
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類型的變量。
注意:為了代碼清晰蒜危,這里并沒有考慮處理異常的情況虱痕。想學(xué)習(xí)更多可以看“Java IO Exception Handling”
Java7開始,你可以用try-with-resources去確保InputStream在使用后可以關(guān)閉辐赞。具體的用法可以參考上面Java異常處理的文章部翘,但是這里有一個例子:
try( InputStream inputstream = new FileInputStream("file.txt") ) {
int data = inputstream.read();
while(data != -1){
System.out.print((char) data);
data = inputstream.read();
}
}
只要線程已經(jīng)執(zhí)行出try代碼塊,inputstream就會被關(guān)閉响委。
read()
InputStream的read()方法返回一個int類型的值新思,這個值是每次讀取的字節(jié)的值。下面是一個相關(guān)的例子:
int data = inputstream.read();
你也可以把int值強轉(zhuǎn)成為一個char類型的:
char aChar = (char) data;
InputStream的子類有可能擴展了read()方法赘风。例如夹囚,DataInputStream允許讀取java基本類型,像int邀窃、long荸哟、float、double瞬捕、boolean等等鞍历。當(dāng)然這些有相應(yīng)的方法,readBoolean()肪虎,readDouble()等等劣砍。
Stream的結(jié)束
如果read()方法返回 -1,就說明流到已經(jīng)全部讀取完畢扇救。這里的 -1 是int類型的刑枝,不是byte或short。這里是有些不同的迅腔!
當(dāng)流去讀完畢的時候仅讽,你可以關(guān)閉它了
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 慎菲,代表讀取結(jié)束。
下面的例子為如何使用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類型變量,去接受每次調(diào)用read(byte[])方法的返回值第煮。
在循環(huán)里解幼,doSomethingWithData()方法被循環(huán)調(diào)用,傳遞進去讀了多少字節(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è)置一個內(nèi)部的標(biāo)記,標(biāo)記在流中哪個數(shù)據(jù)到目前為止已經(jīng)被讀取澄者。使用InputStream的代碼笆呆,可以根據(jù)這個標(biāo)記位來繼續(xù)讀取數(shù)據(jù)。
在讀取流的過程匯總粱挡,如果想退回到標(biāo)記的那點上赠幕,可以調(diào)用reset()方法。然后InputStream退回到標(biāo)記位上询筏,開始從這個位置開始返回數(shù)據(jù)榕堰。這當(dāng)然會導(dǎo)致多次返回一些數(shù)據(jù)
當(dāng)實現(xiàn)一個解析器時,會經(jīng)常用到這兩個方法。解析器讀取一個InputStream時會提前讀逆屡,如果解析器沒有找到它想要的圾旨,他可能需要回退并且將已讀數(shù)據(jù)和其他的數(shù)據(jù)進行匹配。