2011-07-21 25 views
0

我需要擦除我的程序中的文件。我的解決辦法是有一個erase()方法,將做到這一點,像這樣:這裏如何在避免錯誤的同時打開,寫入和保存文件?

public static void erase(String string) { 
    FileWriter fw = null; 
    try { 
     fw = new FileWriter(string); 
     fw.write(new String()); 
    } catch (IOException ie) { 
     e.printStackTrace(); 
    } finally { 
     fw.flush(); 
     fw.close(); 
    } 
} 

幾個問題:

  • 如果fw不正確初始化(不管出於什麼原因,丟失的文件,無效persmissions等),然後當我嘗試在finally塊中關閉它時,會出現NullPointerException。

  • 如果我沒有finally塊,那麼我可能會拋出一個NullPointerException因爲上面的原因。

  • 如果我關閉了try塊內的文件,那麼如果文件正常打開但沒有正確寫入,我可能會泄漏資源。

我忽略了什麼其他問題,我該如何硬化這種方法?

+0

RandomAccessFile.setLength(0)可能更具可讀性(並且可能更正確,因爲字符編碼可能包含一個或兩個BOM字符)。 –

回答

3

你可以只包裹終於在功能的if語句:

if(fw != null){ 
    fw.close(); 
} 

這將確保,如果文件被打開過,那麼它將被關閉。如果它一開始沒有打開,那麼它不會做任何事情,這是你想要的。

另外,我不確定它是否像發佈一樣,但通常不建議在catch塊中打印堆棧跟蹤並繼續(「吞下」異常)。你真的應該讓異常拋出,因爲這可能會隱藏錯誤並且很難追蹤它們。

編輯:見下面的評論。

+2

呃,夥計們,衝突已經發生在結束語中,沒必要在此之前表演。 –

+0

@owlstead:通常它是可能導致closeException()中出現IOException的隱式刷新;而是將flush放在'try'塊中,這意味着接近實際拋出異常將是非常非凡的。 –

1

flush()包含在您的主要區塊中,並且只有close()在捕獲物中。然後關閉前檢查空:

finally { 
    if(fw!=null) { fw.close(); } 
    } 

隨着主塊沖洗,你也可以嘗試/捕捉close和日誌或忽略任何錯誤:

finally { 
    if(fw!=null) { 
     try { fw.close(); } catch(Throwable thr) { log.printError("Close failed: "+thr); thr.printStackTrace(); } 
     } 
    } 

或(一般不推薦使用) :

finally { 
    try { fw.close(); } catch(Throwable thr) {;} 
    } 

編輯

處理我的最好一般的Java成語/ O,IMO是:

FileWriter fw=null; 
try { 
    fw=new FileWriter(string); 
    fw.write(new String()); 
    fw.close(); 
    fw=null; 
    } 
catch(IOException ie) { 
    // do something real here to handle the exception, or don't catch it at all. 
    } 
finally { 
    if(fw!=null) { 
     try { fw.close(); } catch(Throwable thr) { thr.printStackTrace(); } // now we're really out of options 
     } 
    }  

這具有允許catch捕捉和處理由close()本身拋出的異常的重要作用。(該catch條款只應存在,如果你能處理以某種方式除外;做漁獲物和忽視,和一般你不應該簡單地捕捉和跟蹤。)

+0

在finally塊中捕獲'Throwable'(而不是重新拋出)似乎是不明智的,因爲它會隱藏潛在的嚴重問題。捕捉NPE會更有意義......但是,只要檢查null就可以了。 – dhg

+0

@dhg:正如我的第一個建議所做的那樣;但是如果在內部處理IOException,則由於'close()'拋出拋出IOException異常;你必須問自己「*如果* flush已經完成,那麼除了在關閉失敗時記錄錯誤,我還能做什麼」? –

1

以最好的我所知,這是寫代碼的正確習慣的方法:

FileWriter fw = new FileWriter(string); 
try { 
    fw.write(new String()); 
    fw.flush(); 
} catch (IOException ie) { 
    ie.printStackTrace(); 
} finally { 
    fw.close(); 
} 

說明:

  • 如果new FileWriter()引發異常,那麼我們不需要清理任何東西。該方法退出而不執行finally
  • 我們應該把fw.flush()放在try中,而不是finally。有兩個原因:如果寫入失敗,那麼我們不應該煩惱沖洗。另外,如果您將flush()置於finally並且它引發異常,則將跳過close()
+1

進一步的註釋:1.'new String()'與''「''相同。 2.'close()'自動暗示'flush()'。 3.如果你想刪除一個文件,那麼'new File(filepath).delete()'怎麼樣? 4.如果你想使文件爲零字節,那麼'new FileOutputStream(filepath).close()'怎麼樣? – Nayuki

+0

這無法捕獲大多數Writer構造函數拋出的IOException。 –

+0

糟糕,好點。我的錯。 – Nayuki

相關問題