打开和关闭像这样的流有什么问题?

时间:2014-01-28 09:15:59

标签: java try-catch

所以我写了一些代码,Netbeans建议在我实例化sc的同一行上转换为try-with-resources。这个建议会在我将while循环放在sc.close()之后弹出。我不太明白为什么这种近距离操作很糟糕。

        public static void main(String[] args)  {
         try{
             Scanner sc = new Scanner(new File(args[0]));
             while(sc.hasNext()){
                 System.out.println(sc.nextLine());
             }
             sc.close();

         } catch(FileNotFoundException e){
             System.out.println("Het bestand kon niet gevonden worden.");
         } catch(Exception e){
             System.out.println("Onbekende Fout");
         }
    }

7 个答案:

答案 0 :(得分:3)

问题是如果open和close之间的任何内容从方法返回或抛出异常,则不会调用close。

使用try-with-resources(或Java 7 try-finally)来完成关闭,保证每次都关闭流。

答案 1 :(得分:2)

这种方式更好。使用finally可以提供安全操作。

    Scanner sc=null;
    try{
        sc = new Scanner(new File(args[0]));
        while(sc.hasNext()){
            System.out.println(sc.nextLine());
        }           

    } catch(FileNotFoundException e){
        System.out.println("Het bestand kon niet gevonden worden.");
    } catch(Exception e){
        System.out.println("Onbekende Fout");
    } finally {
        if(sc!=null){
        sc.close();
        }
    }

答案 2 :(得分:1)

close()只有在您完成资源后才能完成。如果您在阅读时遇到异常,那么您将跳出该区块并跳过close() 添加finally块,这意味着它会捕获异常,然后调用close()或完成try块,然后调用close()

     Scanner sc = null;
     try{
         sc = new Scanner(new File(args[0]));
         while(sc.hasNext()){
             System.out.println(sc.nextLine());
         }

     } catch(FileNotFoundException e){
         System.out.println("Het bestand kon niet gevonden worden.");
     } catch(Exception e){
         System.out.println("Onbekende Fout");
     }
     finally
     {
        if (sc != null)
          sc.close()
     }

或者如果您使用的是Java 7 try-with-resources更加简单,因为它会为您完成。

 try (Scanner sc = new Scanner(new File(args[0]));)
 {
  ....

答案 3 :(得分:1)

来自Try with resources

上的Java教程
  

try-with-resources语句是一个声明一个的try语句   或更多资源。资源是必须在之后关闭的对象   程序完成了。 try-with-resources语句   确保在语句结束时关闭每个资源。任何   实现java.lang.AutoCloseable的对象,包括all   实现java.io.Closeable的对象可以用作资源。

示例

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}
  

在此示例中,try-with-resources中声明的资源   statement是一个BufferedReader。声明声明出现   在try关键字后面的括号内。班级   Java SE 7及更高版本中的BufferedReader实现了该接口   java.lang.AutoCloseable。因为BufferedReader实例是   在try-with-resource语句中声明,它将被关闭   无论try语句是正常还是突然完成   (由于BufferedReader.readLine方法抛出一个结果   IOException的)。

因此尝试使用资源将负责关闭您的资源。您不再需要编写close()

答案 4 :(得分:1)

问题是,如果您从sc块返回或发生异常,则可能无法关闭try

如果您使用的是Java 7或更高版本,那么try-with-resources版本最好:

public static void main(String[] args)  {
    try (Scanner sc = new Scanner(new File(args[0]))) {
        while(sc.hasNext()){
            System.out.println(sc.nextLine());
        }
    } catch(FileNotFoundException e){
        System.out.println("Het bestand kon niet gevonden worden.");
    } catch(Exception e){
        System.out.println("Onbekende Fout");
    }
}

扫描仪将自动关闭。

如果必须使用Java 6或更早版本,请尝试/ finally:

public static void main(String[] args)  {
    Scanner sc = null;
    try {
        sc = new Scanner(new File(args[0]));
        while(sc.hasNext()){
            System.out.println(sc.nextLine());
        }
    } catch(FileNotFoundException e){
        System.out.println("Het bestand kon niet gevonden worden.");
    } catch(Exception e){
        System.out.println("Onbekende Fout");
    }
    finally {
        if (sc != null) {
            try {
                sc.close();
            }
            catch (Exception) {
            }
        }
    }
}

请注意,在try / finally版本中,我们在sc块之外声明try并将其设置为null,然后设置为finally(将运行try无论null中发生了什么,如果它不是{{1}} 而我们关闭它而不允许该操作抛出异常(因为我们可能已经在抛出一个例外,并且不想打断它。)

答案 5 :(得分:0)

假设由于某种原因读取输入的输入失败:

System.out.println(sc.nextLine());

抛出异常并执行catch (Exception e)块。在这种情况下,您Scanner将不会被关闭。

要在所有情况下关闭Scanner,您应该将sc.close()语句移动到finally块:

try {
    Scanner sc = new Scanner(new File(args[0]));
    while(sc.hasNext()){
        System.out.println(sc.nextLine());
    } 
} catch(FileNotFoundException e){
    System.out.println("Het bestand kon niet gevonden worden.");
} catch(Exception e){
    System.out.println("Onbekende Fout");
} finally {
    if (sc != null) {
        try {
            sc.close();
        }
        catch (Exception) { }
    }
}

为此,您现在可以使用Java 7中引入的Try-with-Resource快捷方式:

try (Scanner sc = new Scanner(new File(args[0]))) {
    while(sc.hasNext()){
         System.out.println(sc.nextLine());
     }
} catch(FileNotFoundException e){
     System.out.println("Het bestand kon niet gevonden worden.");
} catch(Exception e){
     System.out.println("Onbekende Fout");
}

答案 6 :(得分:0)

如果在open()close()之间返回任何内容,则该方法抛出异常,然后不调用close()。做一件事就是尝试评论片段并替换另一段代码,以检查故障是否可以被覆盖。或者,使用在Java 7之后发布的try-with-resources,这将确保每次调用流时都使用close()