Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关闭已在if语句中初始化的PrintWriter对象_Java - Fatal编程技术网

Java 关闭已在if语句中初始化的PrintWriter对象

Java 关闭已在if语句中初始化的PrintWriter对象,java,Java,这可能是一个非常基本的问题,但我正在尝试创建一个Java方法,该方法执行一个进程,读取从该进程创建的inputstream并写入一个新文件。我使用的是Runtime.getRuntime().exec(cmd[]),我想对特定索引使用不同的参数,例如cmd[3]=“something”或cmd[3]=“something other”。我使用for循环来实现这一点,但是对于cmd[3]的参数数组中的第一个索引,我希望它使用PrintWriter打印到一个新文件,因此在for循环顶部初始化它之后,

这可能是一个非常基本的问题,但我正在尝试创建一个Java方法,该方法执行一个进程,读取从该进程创建的inputstream并写入一个新文件。我使用的是Runtime.getRuntime().exec(cmd[]),我想对特定索引使用不同的参数,例如cmd[3]=“something”或cmd[3]=“something other”。我使用for循环来实现这一点,但是对于cmd[3]的参数数组中的第一个索引,我希望它使用PrintWriter打印到一个新文件,因此在for循环顶部初始化它之后,我在if语句中初始化了它。如果我只显示代码,可能会更容易,因此您可以:

public static synchronized void myMethod(String [] argument3, File file) throws IOException{

    String[] cmd = {"command", "argument 1", "argument 2"};
    PrintWriter fileWriter = null;
    Scanner fileScanner = null;
    int i;
    for(i = 0; i < argument3.length; i++){
        fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file,true)));;
        cmd[3] = argument3[i];
        if(i == 0){
            fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file,false)));
        }
        Process p = Runtime.getRuntime().exec(cmd);
        fileScanner = new Scanner(p.getInputStream());

        while(fileScanner.hasNextLine()){
            fileWriter.println(fileScanner.nextLine());
        }
        fileWriter.close();
        fileScanner.close();

    }

}
public static synchronized void myMethod(字符串[]argument3,文件文件)引发IOException{
字符串[]cmd={“命令”、“参数1”、“参数2”};
PrintWriter fileWriter=null;
Scanner fileScanner=null;
int i;
对于(i=0;i<3.length;i++){
fileWriter=newprintwriter(newoutputstreamwriter(newfileoutputstream(file,true));;
cmd[3]=argument3[i];
如果(i==0){
fileWriter=新的PrintWriter(新的OutputStreamWriter(新的FileOutputStream(文件,false));
}
进程p=Runtime.getRuntime().exec(cmd);
fileScanner=newscanner(p.getInputStream());
while(fileScanner.hasNextLine()){
fileWriter.println(fileScanner.nextLine());
}
fileWriter.close();
fileScanner.close();
}
}
所有这些都很好,但在eclipse中,我收到一条警告,说我在if语句中初始化PrintWriter时发生了资源泄漏,所以我有点好奇为什么会这样,因为我在for循环的底部关闭了它们?我知道它没有太大的区别,因为它无论如何都能工作。我只是想尝试正确地清理我的代码。
提前感谢

需要注意的重要事项是

throws IOException
这可以抛出,如果抛出,您的资源将不会关闭。您应该确保您的资源在任何情况下都会关闭,即使抛出异常也是如此。使用

try { ... } finally {   ... close here... } 
…为了这个。想象一下,当您的文件被读取时,发生了一些不好的事情。IOException被抛出,而您的
close()
语句从未被调用,这将是eclipse提到的可怕的资源泄漏

我收到一条警告,说我在if语句中初始化PrintWriter时发生了资源泄漏

问题是:

fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file,true)));
if (i == 0) {
    fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file,false)));
}
fileWriter.close();

第一次通过循环时,当该条件成立时,您将创建两个
打印作者,其中只有第二个关闭。你只是在抛弃第一个。相反,您可以这样初始化它:

fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file, i != 0)));
for (i = 0; i < argument3.length; i++) {
FileOutputStream fos;    
    if (i == 0)
        fos = new FileOutputStream(file, false);
    else
        fos = new FileOutputStream(file, true);
    OutputStreamWriter osw = new OutputStreamWriter(osw);
    fileWriter = new PrintWriter(osw);
    // do the rest
    // and then...
    fileWriter.close();
    fileScanner.close();
    osw.close();
    fos.close();
}
但这就提出了一个问题,为什么每次通过循环都要重新创建
PrintWriter
?只需在循环之外创建一次

另一个问题是,如果抛出异常,则实际上不会执行任何清理代码。您需要的是一个try-catch-finally块,在这里您可以保证您的清理代码被执行。如果您至少使用Java 7,则可以使用,它将自动为您完成所有清理工作:

void myMethod(String [] argument3, File file) throws IOException {
    String[] cmd = {"command", "argument 1", "argument 2"};
    try (PrintWriter fileWriter = new PrintWriter (file)) {
        for (int i = 0; i < argument3.length; i++) {
            Process process = Runtime.getRuntime().exec(cmd);
            try (Scanner fileScanner = new Scanner(process.getInputStream())) {
                cmd[3] = argument3[i];
                while (fileScanner.hasNextLine()) {
                    fileWriter.println(fileScanner.nextLine());
                }
            }
        }
    }
}
void myMethod(字符串[]argument3,文件文件)引发IOException{
字符串[]cmd={“命令”、“参数1”、“参数2”};
try(PrintWriter fileWriter=新的PrintWriter(文件)){
for(int i=0;i
基本上,VM在抱怨,因为两个内部对象从未关闭过

 for(i = 0; i < argument3.length; i++){
        fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file,true)));;
        cmd[3] = argument3[i];
        if(i == 0){
            fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file,false)));
        }
        Process p = Runtime.getRuntime().exec(cmd);
        fileScanner = new Scanner(p.getInputStream());

        while(fileScanner.hasNextLine()){
            fileWriter.println(fileScanner.nextLine());
        }
        fileWriter.close();
        fileScanner.close();

    }
for(i=0;i
您基本上应该像这样分离元素定义:

fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file, i != 0)));
for (i = 0; i < argument3.length; i++) {
FileOutputStream fos;    
    if (i == 0)
        fos = new FileOutputStream(file, false);
    else
        fos = new FileOutputStream(file, true);
    OutputStreamWriter osw = new OutputStreamWriter(osw);
    fileWriter = new PrintWriter(osw);
    // do the rest
    // and then...
    fileWriter.close();
    fileScanner.close();
    osw.close();
    fos.close();
}
for(i=0;i
这将删除警告


注意:如前一个答案所示,将方法移动到
finally
块将被认为是最好的。

使用try-catch-finally块,并在finally块中关闭
扫描仪
PrintWriter
,因为finally始终执行:

public static synchronized void myMethod(String[] argument3, File file) {
        String[] cmd = { "command", "argument 1", "argument 2" };
        PrintWriter fileWriter = null;
        Scanner fileScanner = null;
        try {
            for (int i = 0; i < argument3.length; i++) {
                fileWriter = new PrintWriter(new OutputStreamWriter(
                        new FileOutputStream(file, true)));
                cmd[3] = argument3[i];
                if (i == 0) {
                    fileWriter = new PrintWriter(new OutputStreamWriter(
                            new FileOutputStream(file, false)));
                }
                Process p = Runtime.getRuntime().exec(cmd);
                fileScanner = new Scanner(p.getInputStream());

                while (fileScanner.hasNextLine()) {
                    fileWriter.println(fileScanner.nextLine());
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            fileWriter.close();
            fileScanner.close();
        }
    }
公共静态同步void myMethod(字符串[]argument3,文件){
字符串[]cmd={“命令”、“参数1”、“参数2”};
PrintWriter fileWriter=null;
Scanner fileScanner=null;
试一试{
for(int i=0;i