在循环中进行输入时,如何关闭扫描仪对象?

时间:2018-06-26 10:39:36

标签: java exception

我正在使用while循环从控制台获取输入,并调用我的input()方法。 但是,当我尝试关闭扫描仪对象时,它会给出运行时错误。 当未关闭对象时,程序会正确运行,但日食会警告资源泄漏:'s'永远不会关闭。 如何解决? 我的输入代码是

    String input()
    {
        try
        {
            Scanner s = new Scanner(System.in);
            String str=s.nextLine();
            s.close(); // error because of this 
            return str; 
        }

public class validation  {
    public static void main(String args[])
    {
    try
        {
            String name;
            String email_id;
            String number;
            validation v= new validation();
            do{
            System.out.println("Enter the name");
            name=v.input();
            }
            while (!(v.validate_name(name)) );

            do{
                System.out.println("Enter valid Mobile Number");
                number=v.input();
            }
            while(!(v.validate_number(Long.parseLong(number))) || !(v.filevalidate(number)));

            do{
            System.out.println("Enter valid Email_id");
            email_id=v.input();
            }
            while(!(v.validate_email(email_id)) || !(v.filevalidate(email_id)));

            v.writeToFile(name,number,email_id);
        }       
        catch(Exception e){System.out.println(e);}

错误输出为

  

输入名称   贾斯汀   请输入有效的手机号码   java.util.NoSuchElementException:找不到行   java.lang.NumberFormatException:空

2 个答案:

答案 0 :(得分:0)

String input(){
    Scanner s = null;
    try {
        s = new Scanner(System.in);
        //your code
    }
    finally {
        if(s!=null)
            s.close();
    }
    }

尝试这样并评论您的回复!希望它能正常工作。     我可以看到您的filevalidate和validate_number方法吗?

答案 1 :(得分:0)

关闭Scanner对象会导致它也关闭其关联的InputStream或文件。如果要在Scanner方法中使用input()来从文件而不是从键盘读取数据,则可以这样使用它:

String input() {
    InputStream is = new FileInputStream(INPUT_FILE_NAME);
    Scanner s = new Scanner(is);
    String str = s.nextLine();
    s.close();
    return str;
}

如您所见,扫描仪已关闭,因此没有资源泄漏。如果不关闭它,则在文件上打开的InputStream将保持打开状态。只需关闭扫描仪,也将关闭构造扫描仪的InputStream。因此也无需关闭InputStream。

上面的代码等同于下面的代码,但是下面的代码更安全,因为它可以正确处理异常:

String input() {
    try (
        InputStream is = new FileInputStream(INPUT_FILE_NAME);
        Scanner s = new Scanner(is)
    ) {
        String str = s.nextLine();
        return str;
    }
}

这是try-with-resources语句,您可以在Oracle网站或一本好的教科书上阅读该语句。这样可以确保无论发生什么情况,在方法返回之前,始终关闭InputStream和Scanner。

那我们为什么不对在System.in上打开的扫描仪做同样的事情?这是因为System.in是一个InputStream,我们希望在程序的整个过程中保持打开状态。如果关闭扫描仪,那也将关闭System.in,而我们不希望这样做。但是,既然我们不关闭扫描仪,我们不想每次输入input()方法时都创建一个新的扫描仪。我们只想创建一个可以持续执行程序的扫描程序。一种方法是将其作为字段:

public class Validation {
    private static Scanner in = new Scanner(System.in);

    String input() {
        return in.nextLine();
    }

    ...
}

现在,在JVM加载您的类后立即创建扫描程序,并在您的程序退出之前一直可用。

如果将Scanner对象构造为静态字段,我不确定Eclipse是否仍会抱怨资源泄漏(我不使用Eclipse)。也许您可以告诉我是否这样做。