一、為什么要關(guān)閉流?
涉及到對外部資源的讀寫操作,包括網(wǎng)絡(luò)、硬盤等等的I/O流,如果在使用完畢之后不關(guān)閉,會導(dǎo)致資源泄漏以及可能會引起文件鎖定等問題。因此,需要在使用完畢之后關(guān)閉流。
關(guān)閉流是一種資源釋放機(jī)制,意味著在使用完畢之后歸還系統(tǒng)的內(nèi)存、CPU或者網(wǎng)絡(luò)等資源,避免資源長時間占用。常見的關(guān)閉流的方法是調(diào)用close()方法,該方法會將相關(guān)的資源釋放,可以有效避免導(dǎo)致資源泄漏的問題。
需要注意的是,關(guān)閉流的時機(jī)非常重要,過早關(guān)閉可能會影響正常操作,而過晚關(guān)閉則可能導(dǎo)致資源泄漏。在實際開發(fā)的時候,使用完畢之后應(yīng)該及時關(guān)閉流。在Java 7之后引入了try-with-resources
語法,可以在語法層面上自動關(guān)閉流,用法是:
/* 讀取文件 */
File file = new File("opsLiya.json");
try (FileInputStream fileInputStream = new FileInputStream(file)) {
/* 操作 */
}catch (IOException e){
/* 異常處理 */
}
當(dāng)然也可以使用傳統(tǒng)的finally代碼塊關(guān)閉流:
InputStream inputStream = null;
try {
inputStream = new FileInputStream("opsLiya.txt");
/* 操作 */
} catch (IOException e) {
/* 異常處理 */
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
/* 異常處理 */
}
}
}
二、close方法和flush方法
1.使用close方法
當(dāng)我們使用輸入流的時候,如FileInputStream
,對流進(jìn)行關(guān)閉時,直接調(diào)用close方法即可。
close方法的底層如下:
這個close0方法的底層是一個native方法(本地方法)
此方法進(jìn)行具體的關(guān)閉操作。
2.使用flush方法
當(dāng)我們使用輸出流的時候(即寫入數(shù)據(jù)到文件或者網(wǎng)絡(luò)中),如BufferedOutputStream
,對流進(jìn)行關(guān)閉時,需要先調(diào)用flush方法再調(diào)用close方法。
我們進(jìn)入到BufferedOutputStream
的flush方法的源碼可以看到:
方法注釋大概的意思是:刷新此緩沖輸出流。這將強(qiáng)制將任何緩沖的輸出字節(jié)寫入底層輸出流。
也就是說,在關(guān)閉流前調(diào)用flush方法,會將緩存中的數(shù)據(jù)強(qiáng)行刷新到輸出目標(biāo)中,避免數(shù)據(jù)丟失。
三、流按指向分類
Java中的流在指向上可以分為兩大類,分別是用于讀寫內(nèi)存的流和用于讀寫外部資源(文件、網(wǎng)絡(luò)等)的流。
比如,用于讀寫內(nèi)存的流又可以根據(jù)操作對象分為兩類,如下:
- 操作對象是byte數(shù)組:
- ByteArrayInputStream
- ByteArrayOutputStream
- 操作對象是字符串:
- StringReader
- StringWriter
而用于讀寫外部資源的流,有如下這些:
- FileInputStream和 FileOutputStream:用于字節(jié)流讀寫文件;
- FileReader和FileWriter:用于字符流讀寫文件;
- BufferedInputStream和BufferedOutputStream:用于緩存讀寫字節(jié)流提升IO性能;
- BufferedReader和BufferedWriter:用于緩存讀寫字符流提升IO性能;
- DataInputStream和DataOutputStream:可以用于讀寫整數(shù)、浮點(diǎn)數(shù)等基本類型的字節(jié)流;
- ObjectInputStream和ObjectOutputStream:用于讀寫Java對象的字節(jié)流;
- Socket和ServerSocket:用于網(wǎng)絡(luò)數(shù)據(jù)傳輸;
- HttpURLConnection:用于HTTP請求等。
四、不用關(guān)閉的流
對于Java中的ByteArrayInputStream
和ByteArrayOutputStream
,它們都是在內(nèi)存中進(jìn)行讀寫操作,不需要涉及到底層的外部資源(如文件、網(wǎng)絡(luò)等等),因此在使用完畢后不一定需要顯式地調(diào)用close方法去關(guān)閉。它們占用的內(nèi)存將會被JVM自動回收。
我們可以去到ByteArrayInputStream
的close方法實現(xiàn)是一個空方法,如下:
當(dāng)然,我們也可以手動釋放它們占用的內(nèi)存——使用try-with-resources
語法:文章來源:http://www.zghlxwxcb.cn/news/detail-527297.html
byte[] data = new byte[]{1, 2, 3, 4, 5};
try (ByteArrayInputStream bis = new ByteArrayInputStream(data);
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
/* 操作 */
} catch (IOException e) {
/* 異常處理 */
}
注意:雖然它的close方法是空實現(xiàn),但是我們?yōu)榱吮WC代碼的可讀性和健壯性,仍然應(yīng)該在使用完畢后及時關(guān)閉它們。文章來源地址http://www.zghlxwxcb.cn/news/detail-527297.html
到了這里,關(guān)于【Java基礎(chǔ)】I/O流 —— Java中的流都需要關(guān)閉嗎?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!