2010-09-28 74 views
0

我的代碼利用BufferedReader從文件[main.txt]和PrintWriter讀取以寫入另一個temp [main.temp]文件。我關閉了這兩個流,但我無法在與[main.txt]關聯的File對象上調用delete()方法。只有在關閉兩個流之後調用System.gc()之後,才能刪除File對象。使用delete()刪除文件 - Java

public static boolean delete (String str1, String str2, File FileLoc) 
{ 
    File tempFile = null; 
    BufferedReader Reader = null; 
    PrintWriter Writer = null; 

    try 
    { 
     tempFile = new File (FileLoc.getAbsolutePath() + ".tmp"); 
     Reader = new BufferedReader(new FileReader(FileLoc)); 
     Writer = new PrintWriter(new FileWriter(tempFile)); 
     String lsCurrLine = null; 

     while((lsCurrLine = Reader.readLine()) != null) 
     { 
      // ... 
      // ... 

      if (true) 
      { 
       Writer.println(lsCurrLine); 
       Writer.flush(); 
      } 
     } 

     Reader.close(); 
     Writer.close(); 
     System.gc(); 
    } 
    catch(FileNotFoundException loFileExp) 
    { 
     System.out.println("\n File not found . Exiting"); 
     return false; 
    } 
    catch(IOException loFileExp) 
    { 
     System.out.println("\n IO Exception while deleting the record. Exiting"); 
     return false; 
    } 
} 

這樣可靠嗎?還是有更好的解決辦法?

+1

小心向我們展示您的代碼? – 2010-09-28 03:22:12

+0

@Richard:你能提出建議嗎? – 2010-09-28 03:37:13

+3

你不是在任何地方調用'File.delete()'。只是命名一些任意的方法'刪除'並不意味着它實際上會刪除文件。並談論副作用。如果我在API中找到一個名爲'delete'的方法,我會期望它刪除一些東西,而不是複製數據並創建隨機臨時文件。 – 2010-09-28 04:20:56

回答

3

@ user183717 - 您發佈的代碼顯然不是全部相關的代碼。例如,那些「...」和事實File.delete()實際上沒有在該代碼中調用。

當一個流對象被垃圾回收時,它的終結器會關閉底層的文件描述符。所以,只有當您添加System.gc()調用時,刪除才起作用,這是有力的證據,表明您的代碼不知何故未能關閉文件的某個流。它可能與您發佈的代碼中打開的流對象不同。

正確編寫的流處理代碼使用finally塊來確保流無論如何都會關閉。例如:

Reader reader = new BufferedReader(new FileReader(file)); 
try { 
    // do stuff 
} finally { 
    try { 
     reader.close(); 
    } catch (IOException ex) { 
     // ... 
    } 
} 

如果不遵循這種模式或類似的東西,有一個很好的機會,有場景中流並不總是得到關閉。例如,在您的代碼中,如果其中一個readwrite調用引發異常,您將跳過關閉這些流的語句。

這是[即呼籲System.gc();]可靠嗎?

No.

  1. JVM可能配置爲忽略您的應用程序的gc()調用。
  2. 不能保證丟失的流將無法訪問...但。
  3. 無法保證呼叫System.gc()會注意到流無法訪問。假設,流對象可能被終身僱用,並且調用System.gc()可能僅收集伊甸園空間。
  4. 即使GC發現流不可訪問,也不能保證GC將立即運行終結器。假設,運行終結器可以被無限期推遲...。

還是有更好的解決辦法嗎?

是。修復您的應用程序以正確關閉它的流。

1

嘗試使用的java.io.File庫。這裏的簡單示例:

File f = new File("file path or file name"); 
f.delete(); 
+0

'File.delete()'不起作用,這是問題中的問題。 – 2010-09-28 05:58:52

2

當你說你「關閉兩個流」你的意思是BufferedReaderPrintWriter

在刪除工作之前,您只需要關閉BufferedReader,但您還需要關閉基礎流;通常打電話BufferedReader.close()將做到這一點。這聽起來像你認爲你正在關閉流,但你並沒有真正成功。

您的代碼有一個問題:如果發生異常,您不關閉流。通常最好關閉finally塊中的流。

另外,您發佈的代碼在任何地方都不使用File.delete()...線路究竟做了什麼 - 他們是否將Reader重新分配到新的流中?

+0

發表於以上代碼... – 2010-09-28 03:52:53