我有一个java程序,它在更新时读取日志信息,并将过滤后的数据写入新文件。当我以jar形式执行它时,它将一直运行直到我终止进程。
如何确保在我终止此过程时关闭BufferedReader和BufferedWriter以防止内存泄漏?
我已尝试使用其他人建议的try ... finally块方法,但这会在程序仍在运行时关闭流。提前谢谢。
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 :(得分:1)
要直接回答你的问题,我会在构造函数中创建文件,这样你就可以让代码快速失败并让调用者知道这不会起作用。
然后我会有一个try / finally块包装所有代码,比如
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时,它将根据需要创建新文件或截断。没有必要检查文件是否仍然存在,因为即使它已被删除(这是极不可能的),你也不会使用刚创建的文件。
我不会在main的末尾创建一个新的线程,因为这不会让你获益。
daemon
。给它一个误导性的名字可能会令人困惑。答案 1 :(得分:0)
如果您使用的是Java 7或更高版本,则可以使用try-with-resources来声明您的读者/作者,并且当您终止该过程时,它们应自动关闭。
在您的示例中,它看起来像这样:
try(reader = new BufferedReader(new FileReader(pathToLog));
writer = new BufferedWriter(new FileWriter(pathToOutput));) {
...
}