是这个问题以前也被问过,但这个问题看起来有点复杂。我已经使用了以前问题中与此相关的所有解决方案。
与:释放Java文件句柄有关,无论是什么,Java都会保持文件锁定
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);
}
}
此代码是一个测试代码。我制作了这个测试文件,这样我就可以在我的项目中解决这个问题。
我之所以对此有一个循环,是因为问题发生得太快,无法解释。所以循环是模拟它的最佳方式。在我的项目中,有一个日志文件的配置来选择放在哪里。但如果文件在重新加载时没有在配置中更改。它倾向于将文件锁定并创建额外的文件每次重新加载
我想让这个工作起来。如果这开始正常工作。然后我可以在我的项目中正确地实施它。
您正在创建多个文件,因为您正在创建一个FileHandler,但从未关闭它。
fh = new FileHandler(file.getPath(), append);
...
return new FileHandler(file.getPath(), append);
修复?
return fh;
最后与否完全没有区别。在这种情况下,实际上您确实希望在catch块中关闭,因为如果不关闭,就没有什么能够关闭它。
总是关闭finally块内的资源-
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
}
}
}
使用log方法后,关闭所有处理程序。
this.logger.log(Level.SEVERE, (exception.getClass().getName() + ": " + exception.getMessage()) + "rn" + exception.getCause() + "rn" + "rn");
for (Handler handler : this.logger.getHandlers())
{
handler.close();
}
这里有一个问题:
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;