поток закрывается, когда второй объект вызывает этот метод для входных данных

поток закрывается, пока второй объект вызывает метод getMatrix() для ввода данных #

** Я пытаюсь прочитать данные с клавиатуры, используя объект BufferedReader. для двух матриц, используя два отдельных объекта, при использовании 1-го объекта ввод работает правильно, но при вызове через исключение второго объекта возникает «ПОТОК ЗАКРЫТ», ПОЧЕМУ? каждый объект вызывает метод getMatrix() для добавления данных в матрицу и ввода данных с клавиатуры в этом методе, получает объект Stream для получения данных с клавиатуры и в конце метода закрывает поток, снова вызывает из другого объекта метод getMatrix() и то же самое процесс, но во время второго вызова объекта возникло исключение... Stream Closed...... **

        package myarray; 
        import java.io.BufferedReader;
        import java.io.IOException;
        import java.io.InputStreamReader;
        import java.util.StringTokenizer;

        public class Matrix
        {
            int r,c;
            int arr[][];//instance optional initialization
            public Matrix(int r, int c) 
            {
                super();
                this.r = r;
                this.c = c;
                arr=new int[r][c];
            }
            //Stream closed problem
            protected int[][] getMatrix() throws IOException
            {
            try(BufferedReader br=new BufferedReader(new InputStreamReader(System.in));)
                {
                StringTokenizer st;
                for(int i=0; i<arr.length; i++)
                    {
                    System.out.println("Enter "+arr[i].length+" Integer separated with space");
                    String s=br.readLine();
                    st=new StringTokenizer(s);
                    for(int j=0; j<st.countTokens(); j++)
                        {
                        arr[i][j]=Integer.parseInt(st.nextToken());
                        }
                    }
                return arr;
                }
            }
            //stream end
            protected int [][]findSum(int a[][],int b[][])
            {
                int temp[][]=new int[r][c];//local must be initialize

                for(int i=0; i<a.length; i++)//outer loop
                    for(int j=0; j<a[i].length; j++)//inner loop
                        temp[i][j]=a[i][j]+b[i][j];//inner loop business logic

                return temp;
            }

            //Display the result matrix
            protected void display(int res[][])
            {
                for(int i=0; i<res.length; i++)
                {
                    for(int j=0; j<res[i].length; j++)
                    {
                        System.out.print(res[i][j]+"  ");
                    }
                    System.out.println();
                }
            }

            public static void main(String[] args) throws IOException 
            {
                Matrix m1=new Matrix(3, 3);//3row and 3 column
                Matrix m2=new Matrix(3, 3);

                System.out.println("Enter element for First matrix");
                int x[][]=m1.getMatrix();

                System.out.println("Enter element for Second matrix");
                int y[][]=m2.getMatrix();

                //add matrix and return result a matrix
                int z[][]=m1.findSum(x, y);

                System.out.println("\nThe Sum Matrix is :");
                m2.display(z);

            }
        }
        /* ******OUTPUT******
        Enter element for First matrix
        Enter 3 Integer separated with space
        1 2 3
        Enter 3 Integer separated with space
        4 5 6
        Enter 3 Integer separated with space
        7 8 9
        Enter element for Second matrix
        Exception in thread "main" Enter 3 Integer separated with space
        java.io.IOException: Stream closed
         * */

person Dev    schedule 27.04.2020    source источник


Ответы (2)


Я думаю, что проблема исходит из:

try(BufferedReader br=new BufferedReader(new InputStreamReader(System.in));)

Этот синтаксис называется try-with-resources, который преобразуется в блок try...finally во время компиляции, а после преобразования объект внутри этого блока вызывает метод close() (обратите внимание, что сам объект должен реализовывать интерфейс AutoCloseable для использовать эту функцию). Вот почему в первый раз, когда вы вызываете метод, все нормально, но после этого он закроет BufferedReader, поэтому ошибка говорит: «ПОТОК ЗАКРЫТ»

person Hưng Chu    schedule 27.04.2020
comment
если я использую ресурсы без попытки, то та же проблема через то же исключение - person Dev; 27.04.2020
comment
Следуя документации в файле System.java: /** * Стандартный поток ввода. Этот поток уже * открыт и готов предоставить входные данные. Обычно этот поток * соответствует вводу с клавиатуры или другому источнику ввода, указанному * хост-средой или пользователем. */ public final static InputStream in = null; Как только вы закроете это, вы не сможете открыть его снова - person Hưng Chu; 27.04.2020
comment
если я использую без попытки с ресурсами и метод NOT CLOSE close(), тогда все работает нормально, но я хочу закрыть поток - person Dev; 27.04.2020
comment
Поток (входной/выходной поток) нельзя открыть или воспроизвести снова после того, как он был закрыт. Этот поток ввода соответствует вводу с клавиатуры, поэтому, если вы закроете его, вы не сможете снова вводить данные с клавиатуры в свою программу до завершения работы программы. - person Hưng Chu; 27.04.2020
comment
Спасибо, сэр - person Dev; 27.04.2020

Проблема в том, что вы создаете BufferedReader, используя синтаксис try-with-resources, который закрывает ресурс после использования. Этот синтаксис подходит для чтения данных из файла, но не из System.in, потому что он закрывает не только BufferedReader, но и System.in.

Решение:

Создайте экземпляр BufferedReader без синтаксиса try-with-resources и НЕ закрывайте его.

Сделайте это следующим образом:

protected int[][] getMatrix() throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st;
    for (int i = 0; i < arr.length; i++) {
        System.out.println("Enter " + arr[i].length + " Integer separated with space");
        String s = br.readLine();
        st = new StringTokenizer(s);
        for (int j = 0; j < st.countTokens(); j++) {
            arr[i][j] = Integer.parseInt(st.nextToken());
        }
    }
    return arr;
}
person Arvind Kumar Avinash    schedule 27.04.2020
comment
Да, Арвинд, сэр! Если я не закрываю Stream, тогда все работает нормально - person Dev; 27.04.2020
comment
я знаю, но это возможно, когда я звоню без ресурсов try. но хочу использовать try с ресурсами и каждый раз закрывать поток, тогда какая проблема - person Dev; 27.04.2020
comment
@Dev - Если вы закроете System.in, у вас не будет возможности открыть его снова. - person Arvind Kumar Avinash; 27.04.2020
comment
сэр, я уже сделал тот же код и работает нормально, я хочу знать, почему бы не закрывать поток каждый раз, и если я не закрываю поток, то после завершения второго объекта мой поток открыт. - person Dev; 27.04.2020
comment
@Dev - я предлагаю вам пройти через stackoverflow.com/questions/27286690/ - person Arvind Kumar Avinash; 27.04.2020
comment
Спасибо, сэр - person Dev; 27.04.2020