2014-03-30 4 views
1

У меня есть Java-программа, которая считывает информацию о регистрации, пока она обновляется, и записывает отфильтрованные данные в новый файл. Когда я выполняю это как банку, он будет работать, пока я не убью процесс.Закрытие BufferedReader и BufferedWriter при убийстве Java-процесса

Как я могу убедиться, что когда я убью этот процесс, я закрою BufferedReader и BufferedWriter, чтобы предотвратить утечку памяти?

Я пробовал использовать try ... finally block методы, как это было предложено другими, но это закрывает поток, пока программа все еще работает. Заранее спасибо.

FileWatcher.java

import org.apache.commons.io.FileUtils; 
import org.apache.commons.lang3.StringUtils; 

import java.io.* 

public class FileWatcher implements Runnable 
{ 
    boolean running = true; 
    File file; 
    BufferedReader reader; 
    BufferedWriter writer; 
    String pathToLog, pathToOutput; 

    public FileWatcher(String pathToLog, String pathToOutput) 
    { 
    this.pathToLog = pathToLog; 
    this.pathToOutput = pathToOutput; 
    } 

    public void run() 
    { 
    try 
    { 
     file = new File(pathToOutput); 
     reader = new BufferedReader(new FileReader(pathToLog)); 
     writer = new BufferedWriter(new FileWriter(pathToOutput)); 

     if (!file.exists()) 
     { 
     file.createNewFile(); 
     } 
    } 
    catch (FileNotFoundException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 

    String line = null; 

    System.out.println("Running..."); 
    while (running) 
    { 
     try 
     { 
     /* For each packet logged */ 
     for (int i = 0; i < 7; i++) 
     { 
      line = reader.readLine(); //Analyse text in line 

      /* If no text then break */ 
      if (line == null) 
      { 
      break; 
      } 

      /* If the line begins with valid IP address then break to find Src and Dest IP */ 
      if (line.startsWith("192", 22)) 
      { 
      break; 
      } 
     } 

     /* If line is not null then filter out the Source IP and Destination IP */ 
     if (line != null) 
     { 
      int lastIndexOfSrcIP = StringUtils.ordinalIndexOf(line, ":", 3); // Position to stop reading Source IP 
      int firstIndexOfDestIP = StringUtils.ordinalIndexOf(line, ">", 1) + 2; // Position to start reading Destination IP 
      int lastIndexOfDestIP = StringUtils.ordinalIndexOf(line, ":", 4); // Position to stop reading Destination IP 

      String sourceIP = line.substring(22, lastIndexOfSrcIP); // Source IP 
      String destinationIP = line.substring(firstIndexOfDestIP, lastIndexOfDestIP); // Destination IP 

      /* Check if Source IP is the IP address of the node we are running Snort on 
      * if so then don't append to malicious clients file */ 
      if (!(sourceIP.equals("192.168.7.5"))) 
      { 
      //If Source IP is not in file then add it 
      if (!(FileUtils.readFileToString(file).contains(sourceIP))) 
      { 
       writer.write(sourceIP + "\n"); 
       writer.flush(); 
      } 

      System.out.println(sourceIP + "\t" + destinationIP); 
      } 
     } 
     else 
     { 
      //Sleep whilst there are no new logging alert information 
      try 
      { 
      Thread.sleep(1000); 
      } 
      catch (InterruptedException e) 
      { 
      running = false; 
      writer.close(); 
      reader.close(); 
      } 
     } 
     } 
     catch (IOException e) 
     { 
     e.printStackTrace(); 
     } 
    } 
    } 
} 

Main.java

public class Daemon 
{ 
    public static void main(String[] args) 
    { 
    String pathToLog = args[0]; 
    String pathToOutput = args[1]; 

    Thread daemon = new Thread(new FileWatcher(pathToLog, pathToOutput)); 
    daemon.start(); 
    } 
} 
+0

Использование примерочных с-ресурсов особенностью Java 7. –

ответ

1

Чтобы получить ответ на ваш вопрос, я хотел бы создать файл в конструкторе, это позволяет вам код на провал быстро и пусть вызывающий знайте, что это не сработает.

Я бы тогда попробовать /, наконец, блок, который оборачивает весь код, что-то вроде

public void run() { 
    try { 
     run0(); 
    } catch(Throwable t) { 
     System.err.println("Process dying"); 
     t.printStackTrace(); 
    } finally { 
     // close all resources 
    } 
} 

private void run0() throws Stuff... { 
    // does the real work 
} 

Как я могу убедиться, что, когда я убью этот процесс, что я закрываю BufferedReader и BufferedWriter, чтобы предотвратить память утечки?

Когда вы убиваете процесс, ОС восстанавливает все ресурсы процессов, поэтому вы не можете получить утечку памяти, неважно, как вы ее кодируете. Единственная утечка ресурсов, которую вы можете получить, - это нежелательные временные файлы, оставленные позади.

BTW

  • При вызове FileWriter, это создаст новый файл или обрезать по мере необходимости. Нет смысла проверять, сохраняется ли файл, даже если он был удален (что крайне маловероятно), вы не использовали бы тот, который только что был создан.

  • Я бы не создавал новую нить только в конце основного, так как это ничего не приносит вам.

  • Также я бы назвал поток daemon, если это поток демона. Предоставление им вводящего в заблуждение имени может сбивать с толку.
+0

Спасибо за быстрый ответ. Не могли бы вы объяснить, что вы подразумеваете, не создавая новый поток в конце main? Я не совсем понимаю, что вы подразумеваете под этим – Ballamory

+0

@Balamory. Вы заменяете свой основной поток тем, который вы только что начали. Вы можете просто использовать метод main в методе FileWatcher. –

+0

А я вижу, это немного бессмысленно. – Ballamory

0

Если вы используете Java 7 или более позднюю версию, вы можете использовать try-with-resources, чтобы объявить своих читателей/писателей, и они должны закрываться автоматически, когда вы убиваете процесс.

В вашем примере это будет выглядеть следующим образом:

try(reader = new BufferedReader(new FileReader(pathToLog)); 
    writer = new BufferedWriter(new FileWriter(pathToOutput));) { 
     ... 
} 
+0

'файл' не является закрываемым. –

Смежные вопросы