流是有序的數(shù)據(jù)序列,它...
- 提供通用的I / O模型
- 從底層源或目標(biāo)中提取詳細(xì)信息
無(wú)論您使用流從內(nèi)存畏邢,存儲(chǔ)或網(wǎng)絡(luò)中獲取數(shù)據(jù)慈缔,它都將對(duì)您隱藏實(shí)現(xiàn)細(xì)節(jié)。詳細(xì)信息被抽象掉了琼锋,因此在每種情況下放闺,您都可以將其視為數(shù)據(jù)的有序序列。
- 流類型是單向的
這意味著缕坎,如果創(chuàng)建Java流的實(shí)例怖侦,則可以決定是要寫入Java實(shí)例還是從中讀取。您不能在給定的時(shí)間同時(shí)在單個(gè)流上同時(shí)執(zhí)行這兩項(xiàng)操作谜叹。
我們可以將流分為兩類:
- 字節(jié)流–作為二進(jìn)制數(shù)據(jù)進(jìn)行交互
- 文本流–作為Unicode字符進(jìn)行交互
兩種Java流類型的常規(guī)交互是相同的
用流閱讀
正如我們提到的匾寝,每個(gè)流都用于讀取或?qū)懭搿?/span>
首先,讓我們看看如何從Java流中讀取數(shù)據(jù)荷腊。
在Java中讀取二進(jìn)制數(shù)據(jù)的基類是艳悔。 讀取文本數(shù)據(jù)的基類稱為 類。 InputStreamReader
這兩個(gè)類幾乎具有相同的兩種方法:
- int read()
- int read(byte/char[] buff)
請(qǐng)注意女仰,在兩種情況下猜年,它們都返回一個(gè) Integer 值。這些是解釋值疾忍。整數(shù)是一個(gè)32位容器乔外,因此在兩種情況下都可以使用。
兩者之間的區(qū)別:
- 這個(gè)InputStream與字節(jié)一起工作一罩,字節(jié)是8位杨幼。
- 這個(gè)Reader適用于unicode字符,即16位。
使用InputStream讀取字節(jié)
InputStream input = // create input stream
int result;
while(result = input.read() >= 0) //Indicates the end-of-stream with a return value of -1
byte byteVal = (byte)result;
// do something with byteVal
};
用閱讀器閱讀文字
Reader reader = // create reader
int result;
while(result = reader.read() >= 0)//Indicates the end-of-stream with a return value of -1
char charVal = (char)result;
// do something with charVal
};
請(qǐng)注意差购,如果您想檢索該值四瘫,則只需將結(jié)果轉(zhuǎn)換為適當(dāng)?shù)念愋?在這種情況下為 byte 或 char。
用流寫
為了寫入數(shù)據(jù)欲逃,有兩個(gè)基類類似于讀流找蜜。
- OutputStream(對(duì)于字節(jié))
- Writer (用于文本)
用Java流寫比讀它們更簡(jiǎn)單。兩個(gè)類都有一些write方法void return類型
使用OutputStream寫入字節(jié)
寫作OutputStream暖夭,可以將單個(gè)字節(jié)傳遞給寫方法锹杈,也可以傳遞字節(jié)數(shù)組。
OutputStream output // create output stream;
Byte byteVal = 100;
output.write(byteVal);
byte[] byteBuff = {0, 10, 20};
output.write(byteBuff);
用Writer寫
用Writer你可以傳遞一個(gè)簡(jiǎn)單的字符串迈着,或者一個(gè)字符串類write方法
Writer writer // create output stream;
char charVal = 'c';
writer.write(charVal);
char[] charArray = {'c', 'h', 'a', 'r'};
writer.write(charArray);
String stringVal = "String";
writer.write(stringVal);
正如您所看到的竭望,您需要編寫的代碼比閱讀的代碼少得多。
常見(jiàn)Java流類
上面裕菠,寫了有關(guān)基本流類的文章∫澹現(xiàn)在更深入地討論不同的實(shí)現(xiàn)。
常見(jiàn)的Input / OutputStream派生類
- ByteArrayInputStream / ByteArrayOutputStream 能夠在字節(jié)數(shù)組上創(chuàng)建流
- PipedInputStream / PipedOutputStream –這很像生產(chǎn)者-消費(fèi)者的概念奴潘。管道輸出流可以連接到管道輸入流以創(chuàng)建通信管道旧烧。管道輸出流是管道的發(fā)送端。通常画髓,數(shù)據(jù)是PipedOutputStream通過(guò)一個(gè)線程寫入對(duì)象的掘剪,而數(shù)據(jù)是PipedInputStream通過(guò)其他線程從連接的對(duì)象讀取的。
- FileInputStream / FileOutputStream –這些允許在文件上創(chuàng)建流奈虾。
常見(jiàn)讀/寫實(shí)現(xiàn)
上面是Reader / Writer流實(shí)現(xiàn)的示例夺谁。
- CharArrayReader / Writer 允許在字符上創(chuàng)建流
- StringReader / Writer 允許通過(guò)字符串創(chuàng)建流。
- PipedReader / Writer 允許以文本的生產(chǎn)者/消費(fèi)者關(guān)系創(chuàng)建流肉微。類似于 PipedOutput / InputStream
- InputStreamReader / Writer 允許通過(guò)Input / OutputStream創(chuàng)建流匾鸥。
- FileReader / Writer 能夠在文本文件上進(jìn)行流傳輸。
流式錯(cuò)誤和清理
到目前為止碉纳,我們已經(jīng)了解了streams的一般特性勿负,但還沒(méi)有考慮到與它們一起工作的所有實(shí)際情況。
Stream Realities
清理
- 流由物理存儲(chǔ)支持劳曹,物理存儲(chǔ)通常存在于Java運(yùn)行時(shí)之外奴愉,例如文件或網(wǎng)絡(luò)連接。
- 因此铁孵,Java可能無(wú)法可靠地清除锭硼,因此我們需要進(jìn)行可靠的清除。完成處理后库菲,我們需要關(guān)閉Streams。
解決
- Streams實(shí)現(xiàn)Closeable接口志膀,它實(shí)現(xiàn)一個(gè)單一的close方法熙宇。所以鳖擒,這是我們的責(zé)任。
讓我們看看一個(gè)簡(jiǎn)單的解決方案:
Reader reader;
try{
reader = // create output stream;
// do something with reader;
}catch (IOException e) {
//handle exception
}finally {
if(reader != null)
reader.close();
}
上面這個(gè)例子的問(wèn)題是您總是需要實(shí)現(xiàn)它烫止。通常蒋荚,我們經(jīng)常使用流,所以應(yīng)該自動(dòng)完成馆蠕。讓我們看看怎樣才能實(shí)現(xiàn)期升。
自動(dòng)清理
AutoClosable接口:
1、一種方法:關(guān)閉
2互躬、接口的基本接口 Closable 播赁,因此每個(gè)Stream都支持它。
3吼渡、為嘗試資源提供支持
Try-With-Resources
1容为、自動(dòng)清理一個(gè)或多個(gè)資源“資源”是可以實(shí)現(xiàn)的任何類型??
2、AutoClosable語(yǔ)法類似于傳統(tǒng)的try語(yǔ)句
3寺酪、(可選)包括捕獲塊處理身體處理關(guān)閉方法調(diào)用
使用嘗試資源
在這里坎背,我提供了一個(gè)簡(jiǎn)單的示例,說(shuō)明如何通過(guò)try-with-resources塊使用流的自動(dòng)關(guān)閉寄雀。
我將通過(guò)來(lái)使用它 FileInputStream得滤。稍后我們將討論這個(gè)特定的流。
使用Try-With-Resources
在這里盒犹,我提供了一個(gè)簡(jiǎn)單的示例懂更,說(shuō)明如何通過(guò)try-with-resources塊使用流的自動(dòng)關(guān)閉。
我將通過(guò)來(lái)使用它 FileInputStream阿趁。稍后我們將討論這個(gè)特定的流膜蛔。
try(FileInputStream input = new FileInputStream("file1.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
}
用上述方法,無(wú)需研究進(jìn)一步的工作即可關(guān)閉流脖阵。
概括
在本文中皂股,介紹了Java流的基礎(chǔ)知識(shí),它們是什么命黔,它們?nèi)绾喂ぷ饕约叭绾问褂盟鼈儭?/span>