最近在開發中,使用到IO操作進行反序列化操作,使用了在各種資料中常見的關于IO操作的經典代碼,在自測和測試人員的測試中都沒有發現任何問題!
代碼如下
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;
????}
忽然一天測試人員聯系我說這部分代碼導致系統無法啟動,原因僅僅是因為讓該部分代碼不斷的處理一個為序列化文件!
我仔細分析一下代碼,沒有問題呀,反序列化失敗就直接關閉了ois對象,不可能造成資源泄漏,于是用單步跟蹤的方式
查看處理非法文件的詳細情況:
1、創建FileInputStream 沒有問題
2、創建ObjectInputStream失敗 沒有問題
3、進入catch塊,打印堆棧 沒有問題
4、進入finnaly塊,if (ois != null)為false,這時意識到出問題了
原來創建FileInputStream成功,此時已經申請了資源,但在后續創建ObjectInputStream時失敗,但此時又沒有保存FileInputStream
的引用,無法釋放資源,最終導致了資源泄漏??磥碓谝院蟮?font color="#0000ff">
IO的編程中一定要保存基本流的引用,否則在類似上面的情況
在轉換流失敗后,無法安全的釋放資源!
下面為修改后的代碼:
?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;
????}