最近在開發(fā)中,使用到IO操作進(jìn)行反序列化操作,使用了在各種資料中常見的關(guān)于IO操作的經(jīng)典代碼,在自測(cè)和測(cè)試人員的測(cè)試中都沒有發(fā)現(xiàn)任何問題!
代碼如下
public
?Object?readObject(File?file)
????{
????????Object?o?
=
?
null
;
????????
if
?(file.exists())
????????{
????????????ObjectInputStream?ois?
=
?
null
;
????????????
try
????????????{
????????????????ois?
=
?
new
?ObjectInputStream(
new
?FileInputStream(file));
????????????????o?
=
?ois.readObject();
????????????}
????????????
catch
?(Throwable?e)
????????????{
????????????????e.printStackTrace();
????????????}
????????????
finally
????????????{
????????????????
if
?(ois?
!=
?
null
)
????????????????{
????????????????????
try
????????????????????{
????????????????????????ois.close();
????????????????????}
????????????????????
catch
?(IOException?e)
????????????????????{
????????????????????????e.printStackTrace();
????????????????????}
????????????????}
????????????}????????????
????????}
????????
return
?o;
????}
忽然一天測(cè)試人員聯(lián)系我說這部分代碼導(dǎo)致系統(tǒng)無法啟動(dòng),原因僅僅是因?yàn)樽屧摬糠执a不斷的處理一個(gè)為序列化文件!
我仔細(xì)分析一下代碼,沒有問題呀,反序列化失敗就直接關(guān)閉了ois對(duì)象,不可能造成資源泄漏,于是用單步跟蹤的方式
查看處理非法文件的詳細(xì)情況:
1、創(chuàng)建FileInputStream 沒有問題
2、創(chuàng)建ObjectInputStream失敗 沒有問題
3、進(jìn)入catch塊,打印堆棧 沒有問題
4、進(jìn)入finnaly塊,if (ois != null)為false,這時(shí)意識(shí)到出問題了
原來創(chuàng)建FileInputStream成功,此時(shí)已經(jīng)申請(qǐng)了資源,但在后續(xù)創(chuàng)建ObjectInputStream時(shí)失敗,但此時(shí)又沒有保存FileInputStream
的引用,無法釋放資源,最終導(dǎo)致了資源泄漏。看來在以后的
IO的編程中一定要保存基本流的引用,否則在類似上面的情況
在轉(zhuǎn)換流失敗后,無法安全的釋放資源!
下面為修改后的代碼:
?public?Object?readObject(File?file)
????{
????????Object?o?=?null;
????????if?(file.exists())
????????{
????????????FileInputStream?fis?=?null;
????????????ObjectInputStream?ois?=?null;
????????????try
????????????{
????????????????fis?=?new?FileInputStream(file);
????????????????ois?=?new?ObjectInputStream(fis);
????????????????o?=?ois.readObject();
????????????}
????????????catch?(Throwable?e)
????????????{
????????????????e.printStackTrace();
????????????}
????????????finally
????????????{
????????????????if?(fis?!=?null)
????????????????{
????????????????????try
????????????????????{
????????????????????????fis.close();
????????????????????}
????????????????????catch?(IOException?e)
????????????????????{
????????????????????????e.printStackTrace();
????????????????????}
????????????????}
????????????}????????????
????????}
????????return?o;
????}