终止Java进程时关闭BufferedReader和BufferedWriter
我有一个java程序,它在更新日志信息的同时读取日志信息,并将过滤后的数据写入一个新文件。当我作为一个jar执行这个程序时,它将一直运行,直到我终止这个进程 如何确保在终止此进程时关闭BufferedReader和BufferedWriter以防止内存泄漏 我曾尝试使用其他人建议的try…finally阻塞方法,但这会在程序仍在运行时关闭流。提前谢谢 FileWatcher.java终止Java进程时关闭BufferedReader和BufferedWriter,java,Java,我有一个java程序,它在更新日志信息的同时读取日志信息,并将过滤后的数据写入一个新文件。当我作为一个jar执行这个程序时,它将一直运行,直到我终止这个进程 如何确保在终止此进程时关闭BufferedReader和BufferedWriter以防止内存泄漏 我曾尝试使用其他人建议的try…finally阻塞方法,但这会在程序仍在运行时关闭流。提前谢谢 FileWatcher.java import org.apache.commons.io.FileUtils; import org.apach
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();
}
}
}
}
为了直接回答您的问题,我将在构造函数中创建文件,这允许您的代码快速失败,并让调用者知道这是行不通的 然后我会有一个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以防止内存泄漏
当您杀死一个进程时,操作系统将回收所有进程资源,这样无论您如何编写它,都不会出现内存泄漏。唯一可以得到的资源泄漏是留下不需要的临时文件
顺便说一句
- 当您调用FileWriter时,它将创建一个新文件或根据需要截断。没有必要检查文件是否仍然存在,因为即使它已被删除(这是极不可能的),您也不会使用刚刚创建的文件
- 我不会在main的末尾创建一个新线程,因为这对您没有任何好处
- 而且,如果线程是守护进程线程,我只会调用线程
守护进程
。给它起一个误导性的名字可能会让人困惑
try(reader = new BufferedReader(new FileReader(pathToLog));
writer = new BufferedWriter(new FileWriter(pathToOutput));) {
...
}
使用Java 7的资源试用功能。
文件
不可关闭。感谢您的快速响应。你能解释一下不在main的末尾创建一个新线程是什么意思吗?我不太明白你的意思that@Balamory您正在用刚开始的线程替换主线程。您可以让主方法在FileWatcher中调用一个方法。
try(reader = new BufferedReader(new FileReader(pathToLog));
writer = new BufferedWriter(new FileWriter(pathToOutput));) {
...
}