2013-08-22 90 views
0

是的這個問題之前已經被問過,但問題看起來似乎更復雜一點。我已經使用了與以前相關的所有問題的解決方案。Java文件句柄將不會關閉

涉及:Freeing Java File HandlesJava keeps file locks no matter what

package me.test; 

import java.io.File; 
import java.util.logging.FileHandler; 
import java.util.logging.Formatter; 
import java.util.logging.Level; 
import java.util.logging.LogRecord; 
import java.util.logging.Logger; 

public class Test { 
    Logger log = Logger.getAnonymousLogger(); 
    FileHandler handle; 

    final static String newline = System.lineSeparator(); 
    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     Test t = new Test(); 
     t.run(); 
    } 
    public void run() 
    { 
     for (int i = 0; i < 6; i++) { 
      testLogs(); 
      change(); 
     } 
     testLogs(); 
     if (handle != null) 
     { 
      handle.close(); 
      log.removeHandler(handle); 
     } 
    } 
    public static FileHandler craftFileHandler(File file, boolean append) 
    { 
     if (file == null) 
      return null; 
     FileHandler fh = null; 
     try { 
      fh = new FileHandler(file.getPath(), append); 
      fh.setFormatter(new Formatter() { 

       @Override 
       public String format(LogRecord record) { 
        return "[test] " + "[" + record.getLevel().toString() + "]" + String.format(record.getMessage(), record.getParameters()) + newline; 
       } 
      }); 
      return new FileHandler(file.getPath(), append); 
     } catch (Exception e) { 
      if (fh != null) 
       fh.close(); 
      return null; 
     } 
    } 

    public void change() 
    { 
     if (handle != null) 
     { 
      handle.flush(); 
      handle.close(); 
      log.removeHandler(handle); 
     } 
     handle = null; 
     File f = new File("log.log"); 
     handle = craftFileHandler(f, true); 
     System.out.println(f.getAbsolutePath()); 
     if (handle != null) 
      log.addHandler(handle); 
    } 
    public void testLogs() 
    { 
     if (log == null) 
     { 
      log = Logger.getLogger("test"); 
      log.setLevel(Level.ALL); 
     } 
     log.info("This is info #1"); 
     log.warning("Warning 1"); 
     log.info("meh info again."); 
     log.severe("SEVERE HELL YA NICE TEST"); 
     log.info("You sure its good here?"); 
     log.info("Handler count " + log.getHandlers().length); 
    } 
} 

此代碼,就是要測試的代碼。我做了這個測試文件,所以我可以弄清楚如何解決這個問題,我有一個項目。

我有這個循環的原因是因爲問題發生得太快而無法解釋。所以一個循環是模擬它的最好方法。在我的項目中有一個日誌文件的配置來選擇放置它的位置。但是如果該文件在其重新加載時沒有在配置中更改。它傾向於將文件鎖定並創建額外的文件每一個重新加載

我想得到這個工作。如果這開始正常工作。然後我可以在我的項目中正確實施它。

+0

我的代碼在這篇文章中看起來很雜亂。我將用更簡潔的代碼更新帖子。確保它會導致同樣的問題。然後,我會嘗試查看最佳答案,並在研究發生了什麼問題後發佈更多信息。 – CoasterChris

回答

1

你得到創建,因爲你正在創建一個文件處理器,從不多個文件關閉它。

fh = new FileHandler(file.getPath(), append); 
... 
return new FileHandler(file.getPath(), append); 

修復?

return fh; 

最後還是沒有變得完全沒有區別。在這種情況下,你實際上想要在catch塊中關閉,因爲如果你不這樣做,任何東西都不能關閉它。

+0

必須在那裏發生意外。這也是代碼中的問題之一。 – CoasterChris

+0

這個解決方案解決了代碼的所有問題。 – CoasterChris

0

那麼,一個問題就在這裏:

try { 
      fh = new FileHandler(file.getPath(), append); 
      fh.setFormatter(new Formatter() { 

       @Override 
       public String format(LogRecord record) { 
        return "[test] " + "[" + record.getLevel().toString() + "]" + String.format(record.getMessage(), record.getParameters()) + newline; 
       } 
      }); 
      return new FileHandler(file.getPath(), append); 
     } catch (Exception e) { 
      if (fh != null) 
       fh.close(); 
      return null; 

你永遠不會關閉該文件在try語句,只有關閉它,如果有一個錯誤。您應該儘快關閉該文件,你用它做:內

try { 
      fh = new FileHandler(file.getPath(), append); 
      fh.setFormatter(new Formatter() { 

       @Override 
       public String format(LogRecord record) { 
        return "[test] " + "[" + record.getLevel().toString() + "]" + String.format(record.getMessage(), record.getParameters()) + newline; 
       } 
      }); 
      //close fh 
      fh.close(); 
      return new FileHandler(file.getPath(), append); 
     } catch (Exception e) { 
      if (fh != null) 
       fh.close(); 
      return null; 
+0

重讀您的代碼。你創建一個新的FileHandler fh返回。 然後你關閉它,並重新創建一個新的沒有使用原來的?合理? – CoasterChris

2

始終關閉資源終於塊級

try { 
    fh = new FileHandler(file.getPath(), append); 
    fh.setFormatter(new Formatter() { 

    @Override 
    public String format(LogRecord record) { 
     return "[test] " + "[" + record.getLevel().toString() + "]" + String.format(record.getMessage(), record.getParameters()) + newline; 
    } 
    }); 
    return new FileHandler(file.getPath(), append); 
} catch (Exception e) { 

    return null; 
    // never close in catch 

} finally { 
    // lastly close anything that may be open 
    if (fh != null){ 
     try { 
      fh.close(); 
     } catch (Exception ex){ 
      // error closing 
     } 
    } 
} 
+0

當你要返回一個對象時,這將如何工作(實質上退出try語句) – CoasterChris

+2

@CoasterChris這就是它的美妙之處。 try中的return語句將存儲處理程序,直到finally塊完成並返回。最後總是會被執行,除非你關掉電腦。捕獲同樣的事情。在返回null之前,最終會被執行,然後返回null。 –

+0

Dutta我爲此感謝你。我確實嘗試了try塊。 jvm現在困惑了我。但近距離聲明應該是有效的。你有沒有在代碼的其他地方看到過密切的陳述任何想法如何不起作用? – CoasterChris

0

使用log方法關閉所有處理程序後。

this.logger.log(Level.SEVERE, (exception.getClass().getName() + ": " + exception.getMessage()) + "\r\n" + exception.getCause() + "\r\n" + "\r\n"); 

    for (Handler handler : this.logger.getHandlers()) 
    { 
     handler.close(); 
    } 
相關問題