欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java之如何關(guān)閉流

 更新時間:2022年11月22日 09:08:52   作者:思想永無止境  
這篇文章主要介紹了Java之如何關(guān)閉流問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

我們深知在操作Java流對象后要將流關(guān)閉,但往往事情不盡人意,大致有以下幾種不能一定將流關(guān)閉的寫法:

1.在try中關(guān)流,而沒在finally中關(guān)流

try {
	OutputStream out = new FileOutputStream("");
	// ...操作流代碼
	out.close();
} catch (Exception e) {
	e.printStackTrace();
}

正確寫法:

OutputStream out = null;
try {
	out = new FileOutputStream("");
	// ...操作流代碼
} catch (Exception e) {
	e.printStackTrace();
} finally {
	try {
		if (out != null) {
			out.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

2.在關(guān)閉多個流時因?yàn)橄勇闊⑺嘘P(guān)流的代碼丟到一個try中

OutputStream out = null;
OutputStream out2 = null;
try {
	out = new FileOutputStream("");
	out2 = new FileOutputStream("");
	// ...操作流代碼
} catch (Exception e) {
	e.printStackTrace();
} finally {
	try {
		if (out != null) {
			out.close();// 如果此處出現(xiàn)異常,則out2流沒有被關(guān)閉
		}
		if (out2 != null) {
			out2.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

正確寫法:

OutputStream out = null;
OutputStream out2 = null;
try {
	out = new FileOutputStream("");
	out2 = new FileOutputStream("");
	// ...操作流代碼
} catch (Exception e) {
	e.printStackTrace();
} finally {
	try {
		if (out != null) {
			out.close();// 如果此處出現(xiàn)異常,則out2流也會被關(guān)閉
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
	try {
		if (out2 != null) {
			out2.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

3.在循環(huán)中創(chuàng)建流

在循環(huán)外關(guān)閉,導(dǎo)致關(guān)閉的是最后一個流

OutputStream out = null;
try {
	for (int i = 0; i < 10; i++) {
		out = new FileOutputStream("");
		// ...操作流代碼
	}
} catch (Exception e) {
	e.printStackTrace();
} finally {
	try {
		if (out != null) {
			out.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

正確寫法:

for (int i = 0; i < 10; i++) {
	OutputStream out = null;
	try {
		out = new FileOutputStream("");
		// ...操作流代碼
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		try {
			if (out != null) {
				out.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

4.在Java7中

關(guān)閉流這種繁瑣的事情再也不用我們自己敲代碼了

try (OutputStream out = new FileOutputStream("")){
	// ...操作流代碼
} catch (Exception e) {
	e.printStackTrace();
}

只要實(shí)現(xiàn)的自動關(guān)閉接口(Closeable)的類都可以在try結(jié)構(gòu)體上定義,java會自動幫我們關(guān)閉,及時在發(fā)生異常的情況下也會??梢栽趖ry結(jié)構(gòu)體上定義多個,用分號隔開即可,如:

try (OutputStream out = new FileOutputStream("");OutputStream out2 = new FileOutputStream("")){
	// ...操作流代碼
} catch (Exception e) {
	throw e;
}

注:Android SDK 20版本對應(yīng)java7,低于20版本無法使用try-catch-resources自動關(guān)流。

5.內(nèi)存流可以不用關(guān)閉(關(guān)與不關(guān)都可以,沒影響)

ByteArrayOutputStream和ByteArrayInputStream其實(shí)是偽裝成流的字節(jié)數(shù)組(把它們當(dāng)成字節(jié)數(shù)據(jù)來看就好了),他們不會鎖定任何文件句柄和端口,如果不再被使用,字節(jié)數(shù)組會被垃圾回收掉,所以不需要關(guān)閉。

6.使用裝飾流時,只需要關(guān)閉最后面的裝飾流即可

裝飾流是指通過裝飾模式實(shí)現(xiàn)的java流,又稱為包裝流,裝飾流只是為原生流附加額外的功能(或效果),java中的緩沖流、橋接流也是屬于裝飾流。

        InputStream is=new FileInputStream("C:\\Users\\tang\\Desktop\\記事本.txt");
		InputStreamReader isr=new InputStreamReader(is);
		BufferedReader br = new BufferedReader(isr);
		String string = br.readLine();
		System.out.println(string);
		try {
			br.close();//只需要關(guān)閉最后的br即可
		} catch (Exception e) {
			e.printStackTrace();
		}

裝飾流關(guān)閉時會調(diào)用原生流關(guān)閉,請看源碼:

   //BufferedReader.java
    public void close() throws IOException {
        synchronized (lock) {
            if (in == null)
                return;
            try {
                in.close();//這里的in就是原生流
            } finally {
                in = null;
                cb = null;
            }
        }
    }
//InputStreamReader.java
public void close() throws IOException {
        sd.close();//這里的sd就是原生流的解碼器(StreamDecoder),解碼器的close會調(diào)用原生流的close
    }

有這樣層層關(guān)閉的機(jī)制,我們就只需要關(guān)閉最外層的流就行了(甚至博主認(rèn)為,其實(shí)只關(guān)閉最里層的流也可以,因?yàn)檠b飾流并不持有任何文件句柄和端口,它和內(nèi)存流一樣是個“假流”,當(dāng)然這只是我的個人推理,不敢保證只關(guān)閉最里層的流一定沒有問題)。

7.關(guān)閉流時的順序問題

兩個不相干的流的關(guān)閉順序沒有任何影響,如:

out1 = new FileOutputStream("");
out2 = new FileOutputStream("");
//這里的out1和out2誰先關(guān)誰后關(guān)都一樣,沒有任何影響

如果兩個流有依賴關(guān)系,那么你可以像上面說的,只關(guān)閉最外層的即可。

如果不嫌麻煩,非得一個個關(guān)閉,那么需要先關(guān)閉最里層,從里往外一層層進(jìn)行關(guān)閉。

為什么不能從外層往里層逐步關(guān)閉?原因上面講裝飾流已經(jīng)講的很清楚了,關(guān)閉外層時,內(nèi)層的流其實(shí)已經(jīng)同時關(guān)閉了,你再去關(guān)內(nèi)層的流,就會報錯

至于網(wǎng)上說的先聲明先關(guān)閉,就是這個道理,先聲明的是內(nèi)層,最先申明的是最內(nèi)層,最后聲明的是最外層。

分割線-----------------------------

其實(shí)jdk8版的順序隨便打亂關(guān)閉都不會報錯,因?yàn)樽罾锩娴挠信袛啵绻饕呀?jīng)關(guān)閉直接return)。

可以看FileInputStream源碼:

public void close() throws IOException {
        synchronized (closeLock) {
            if (closed) {
                return;
            }
            closed = true;
        }
        if (channel != null) {
           channel.close();
        }
 
        fd.closeAll(new Closeable() {
            public void close() throws IOException {
               close0();
           }
        });
    }

其他jdk版本,博主時間有限沒有測試,各位還是遵循老辦法(分割線前面的)關(guān)閉吧。

8.深究為什么一定要關(guān)閉流的原因

一個流綁定了一個文件句柄(或網(wǎng)絡(luò)端口),如果流不關(guān)閉,該文件(或端口)將始終處于被鎖定(不能讀取、寫入、刪除和重命名)狀態(tài),占用大量系統(tǒng)資源卻沒有釋放。

9.推薦使用NIO的Files工具類替換FileInputStream和FileOutputStream

public static?List<String> readAllLines(Path path, Charset cs)//以字符流方式讀取所有行

public static Path write(Path path, Iterable<? extends CharSequence> lines,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Charset cs, OpenOption... options)//以字符流方式寫入指定行

public static?byte[] readAllBytes(Path path)//以字節(jié)流方式讀取所有字節(jié)

public static Path write(Path path, byte[] bytes, OpenOption... options)//以字節(jié)流方式寫入指定字節(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Maven介紹與配置+IDEA集成Maven+使用Maven命令小結(jié)

    Maven介紹與配置+IDEA集成Maven+使用Maven命令小結(jié)

    Maven是Apache軟件基金會的一個開源項(xiàng)目,是一個優(yōu)秀的項(xiàng)目構(gòu)建管理工具,它用來幫助開發(fā)者管理項(xiàng)目中的 jar,以及 jar 之間的依賴關(guān)系、完成項(xiàng)目的編譯、測試、打包和發(fā)布等工作,本文給大家介紹Maven介紹與配置+IDEA集成Maven+使用Maven命令,感興趣的朋友一起看看吧
    2024-01-01
  • JAVA實(shí)戰(zhàn)練習(xí)之圖書管理系統(tǒng)實(shí)現(xiàn)流程

    JAVA實(shí)戰(zhàn)練習(xí)之圖書管理系統(tǒng)實(shí)現(xiàn)流程

    隨著網(wǎng)絡(luò)技術(shù)的高速發(fā)展,計(jì)算機(jī)應(yīng)用的普及,利用計(jì)算機(jī)對圖書館的日常工作進(jìn)行管理勢在必行,本篇文章手把手帶你用Java實(shí)現(xiàn)一個圖書管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-10-10
  • Mybatis-Plus的使用詳解

    Mybatis-Plus的使用詳解

    這篇文章主要介紹了Mybatis-Plus的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • JavaSE?XML解析技術(shù)的使用方法詳解

    JavaSE?XML解析技術(shù)的使用方法詳解

    XML意為可擴(kuò)展標(biāo)記語言,被多數(shù)技術(shù)人員用以選擇作為數(shù)據(jù)傳輸?shù)妮d體,成為一種通用的數(shù)據(jù)交換格式,下面這篇文章主要給大家介紹了關(guān)于JavaSE?XML解析技術(shù)的使用方法,需要的朋友可以參考下
    2023-04-04
  • Idea如何使用Fast Request接口調(diào)試

    Idea如何使用Fast Request接口調(diào)試

    這篇文章主要介紹了Idea如何使用Fast Request接口調(diào)試問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • SpringBoot實(shí)現(xiàn)文件在線預(yù)覽功能的全過程

    SpringBoot實(shí)現(xiàn)文件在線預(yù)覽功能的全過程

    我們開發(fā)業(yè)務(wù)系統(tǒng)的時候,經(jīng)常有那種文檔文件在線預(yù)覽的需求,下面這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)文件在線預(yù)覽功能的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 簡單的java讀取文件示例分享

    簡單的java讀取文件示例分享

    這篇文章主要介紹了java讀取txt文件內(nèi)容,示例很簡單,代碼里有注釋,大家直接看代碼吧
    2014-01-01
  • Java 常見的幾種內(nèi)存溢出異常的原因及解決

    Java 常見的幾種內(nèi)存溢出異常的原因及解決

    這篇文章主要介紹了Java 常見的幾種內(nèi)存溢出異常及解決,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-04-04
  • java8傳函數(shù)方法圖文詳解

    java8傳函數(shù)方法圖文詳解

    在本篇文章中小編給大家整理了關(guān)于java8傳函數(shù)方法和相關(guān)知識點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-04-04
  • Spring通過配置文件管理Bean對象的方法

    Spring通過配置文件管理Bean對象的方法

    這篇文章主要介紹了Spring通過配置文件管理Bean對象的相關(guān)知識,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07

最新評論