經(jīng)典的IO代碼為什么有資源泄漏?
最近在開發(fā)中,使用到IO操作進(jìn)行反序列化操作,使用了在各種資料中常見的關(guān)于IO操作的經(jīng)典代碼,在自測和測試人員的測試中都沒有發(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;
????}
????{
????????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;
????}
忽然一天測試人員聯(lián)系我說這部分代碼導(dǎo)致系統(tǒng)無法啟動(dòng),原因僅僅是因?yàn)樽屧摬糠执a不斷的處理一個(gè)為序列化文件!
我仔細(xì)分析一下代碼,沒有問題呀,反序列化失敗就直接關(guān)閉了ois對象,不可能造成資源泄漏,于是用單步跟蹤的方式
查看處理非法文件的詳細(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)申請了資源,但在后續(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;
????}
????{
????????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;
????}
posted on 2006-03-24 21:47 mooninwell 閱讀(1387) 評論(10) 編輯 收藏 所屬分類: Java原創(chuàng)