2013-08-22 3 views
0

Да Этот вопрос задан, прежде чем проблема будет немного сложнее, чем кажется. Я использовал все решения из предыдущих вопросов, которые касаются этого.Файлы Java-файлов не закрываются

Касается:Freeing Java File Handles , Java 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); 
    } 
} 

Этот код предназначен быть тестовый код. Я сделал этот тестовый файл, чтобы понять, как исправить эту проблему в проекте, который у меня есть.

Причина, по которой я столкнулся, состоит в том, что проблема возникает слишком быстро, чтобы объяснить. Таким образом, цикл был лучшим способом имитировать его. В моем проекте есть конфиг для файла журнала, чтобы выбрать, куда его поместить. Но если файл не изменен в config при его перезагрузке. Он имеет тенденцию оставлять файл заблокированным и создавать дополнительные файлы. EVERY reload

Я хотел бы получить эту работу. Если это нормально работает. Тогда я могу правильно реализовать его в своем проекте.

+0

Этот код выглядит беспорядочным в этом сообщении. Я буду обновлять сообщение с помощью более чистого кода. Удостовериться, что это приводит к той же проблеме. Затем я попытаюсь найти лучший ответ и сообщить об этом после изучения того, что происходит неправильно. – CoasterChris

ответ

1

Вы получаете несколько файлов, созданных, потому что вы создаете FileHandler и никогда закрывая его.

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 { 
      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 Вот в чем его красота. Оператор return внутри try хранит обработчик до тех пор, пока блок finally не будет завершен, а затем вернется. наконец, всегда выполняется, если, конечно, вы не выключите компьютер. То же самое происходит и для улова. Прежде чем возвращать null, он, наконец, будет выполнен, а затем возвращается null. –

+0

Dutta Я благодарю вас за это. Я попытался выполнить блок try. Теперь jvm смутил меня. Но тесные заявления должны были работать в любом случае. Вы видели закрытые заявления в другом месте кода? Любые идеи о том, как это не работает? – CoasterChris

0

После использования метод журнала закрывает все обработчики.

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(); 
    } 
Смежные вопросы