如何在java中有效地组织代码来关闭文件

时间:2015-05-30 03:59:24

标签: java

我正在尝试用Java中的文件读取内容然后将其关闭。但我不知道在哪里放近的方法。

    try {
        Scanner scanner = new Scanner(new FileInputStream("data"));
        while (scanner.hasNext()){
            String line = scanner.nextLine().trim();
            set.add(line);
        }
        //scanner.close();
    } catch (FileNotFoundException e) {
        System.out.println("data is not found");
        e.printStackTrace();
    } finally{
        //scanner.close();
    }

正如你在代码中看到的那样,我可以将close方法放在两个地方,一个在try里面,一个在里面。 如果我把它放在try子句中,那么之后就会失败,扫描器无法关闭;但是,如果我把它放在finally子句中,我需要在try-clause之前声明扫描器,这样,如果文件打开失败,则finally中的close方法没有意义,因为scanner仍然是null。

我知道这些想法肯定有问题,有人可以指出吗?

5 个答案:

答案 0 :(得分:2)

如果您使用的是Java 8,我强烈建议您使用try-with-resources

try (Scanner scanner = new Scanner(new FileInputStream("data"))) {
    while (scanner.hasNext()) {
        String line = scanner.nextLine().trim();
        set.add(line);
    }
} catch (FileNotFoundException e) {
    System.out.println("data is not found");
    e.printStackTrace();
}

使用此模式,java会隐式添加finally块来调用scanner.close()

如果您无法利用Java 8的功能,那么最好的选择是在scanner块之前声明try,并在finally中关闭它时检查null :

Scanner scanner = null;
try {
    scanner = new Scanner(new FileInputStream("data"));
    while (scanner.hasNext()) {
        String line = scanner.nextLine().trim();
        set.add(line);
    }
} catch (FileNotFoundException e) {
    System.out.println("data is not found");
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

答案 1 :(得分:1)

试试这个

Scanner scanner = null;
try {
    scanner = new Scanner(new FileInputStream("data"));
    while (scanner.hasNext()){
        String line = scanner.nextLine().trim();
        set.add(line);
    }
    //scanner.close();
} catch (FileNotFoundException e) {
    System.out.println("data is not found");
    e.printStackTrace();
} finally{
    if(scanner != null)
         scanner.close();
}

答案 2 :(得分:1)

对此使用try-with-resources的正确方法是单独从扫描程序打开文件:

try (FileInputStream fis = new FileInputStream(...);
    Scanner scanner = new Scanner(fis))
{
    // ...
}
catch ...

如果两个流存在,它们将被关闭。

答案 3 :(得分:0)

正常的习惯用语(我感到惊讶,没有人表现出来)是在尝试之前声明变量而没有初始化,然后在try中设置它。为了得到你想要的东西,你要说......

Scanner scanner;
try {
    scanner = new Scanner(new FileInputStream("data"));
    while (scanner.hasNext()){
        String line = scanner.nextLine().trim();
        set.add(line);
    }
} catch (FileNotFoundException e) {
    System.out.println("data is not found");
    e.printStackTrace();
} finally{
    scanner.close();
}

然而,这不是正确的方法。如果try / catch应该只包含可以生成未找到的异常的代码,那将是最好的。那个文件打开了。如果您需要(未在下面完成),请将try / catch重构为自己的私有方法。

FileInputStream fis;
try {
  fis = new FileInputStream("data")
} catch (FileNotFoundException e) {
  System.out.println("data is not found");
  e.printStackTrace();
  return;  // Or you can throw another exception here...
}
// Properly used scanners don't raise exceptions, so
// putting this in a try catch block is poor practice.
// (IOExceptions of the stream are caught by the scanner
// and treated as end-of-input.)
Scanner scanner = new Scanner(fis);
while (scanner.hasNextLine() {
  String line = scanner.nextLine().trim();
  set.add(line);
}
scanner.close();

答案 4 :(得分:-1)

您可以使用此方法,该方法遵循while(hasNext()) - >的迭代器模式。阅读 - >关闭。

    try {
            Scanner scanner = new Scanner(new FileInputStream("data"));
            while (scanner.hasNext()){
                String line = scanner.nextLine().trim();
                set.add(line);
            }
            scanner.close();
        } catch (FileNotFoundException e) {
            System.out.println("data is not found");
            e.printStackTrace();
        } finally{
        }

这样,如果文件成功打开,扫描程序不为空,然后在读取对象后关闭扫描程序。那里不应该有例外,如果您认为可能存在例外,您可以添加嵌套的try块来捕获读取异常。然后在第一个试块中关闭扫描仪。