Как закрыть объект сканера, когда ввод выполняется в цикле? - PullRequest
0 голосов
/ 26 июня 2018

Я беру ввод с консоли, используя цикл 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: null

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

При закрытии объекта 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;
    }
}

Это заявление о попытках использования ресурсов, о котором вы можете прочитать на веб-сайте 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 загружает ваш класс, и остается доступным для использования до выхода из вашей программы.

Я не уверен, будет ли Eclipse по-прежнему жаловаться на утечку ресурсов, если вы создадите объект Scanner как статическое поле (я не использую Eclipse). Возможно, вы можете дать мне знать, если это так.

0 голосов
/ 26 июня 2018
String input(){
    Scanner s = null;
    try {
        s = new Scanner(System.in);
        //your code
    }
    finally {
        if(s!=null)
            s.close();
    }
    }

попробуй вот так и прокомментируй свой ответ! Надеюсь, это работает нормально. Могу ли я увидеть ваши методы filevalidate и validate_number!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...