如何修复ioexception流关闭?

时间:2017-07-06 05:17:51

标签: java stream bufferedreader filereader

启动时,我的程序给我发消息java.io.IOException:stream closed。然后打开有限的组件。

我理解流关闭的异常是什么,在我的情况下,我无法弄清楚如何修复它。我真的很感激一些帮助。 (我很抱歉大量的代码,但我不确定你需要什么来帮助我)

 try {
    //Defines new file reader and buffered reader
    FileReader file_to_read = new FileReader(path);
    BufferedReader br1 = new BufferedReader(file_to_read);

    //action code

        try {
        //Finds the line number to see the number of cards in each set
        lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
        lnr2.skip(Long.MAX_VALUE);
        strLineNumber2 = String.valueOf(lnr2.getLineNumber());
        lineNumber2 = Integer.parseInt(strLineNumber2);

        //Closes the file reader and buffered reader
        br1.close();
        file_to_read.close();

    } catch (IOException | NumberFormatException e) {
        strLineNumber2 = "0";
    }           
        //Adds the set name to the set name array
        lblDeckName[row] = new JLabel (strSetName);

        //Adds all buttons that will be used in the layout into a button array
        JButton aryOptions [][] = new JButton [3][lineNumber];

        //Defines and formats the Add Words button
        JButton btnAddWords = new JButton("Add Words"); 
        btnAddWords.setOpaque(false);
        btnAddWords.setContentAreaFilled(false);
        btnAddWords.setBorder(null);
        btnAddWords.setBorderPainted(false);

        //Defines and formats the Play button
        JButton btnPlay = new JButton("Play");
        btnPlay.setOpaque(false);
        btnPlay.setContentAreaFilled(false);
        btnPlay.setBorder(null);
        btnPlay.setBorderPainted(false);

        //Defines and formats the Delete Set button
        JButton btnDelete = new JButton("Delete Set");
        btnDelete.setOpaque(false);
        btnDelete.setContentAreaFilled(false);
        btnDelete.setBorder(null);
        btnDelete.setBorderPainted(false); 

        //Adds each button to the array based on the number of sets
        aryOptions [0][row] = btnAddWords;
        aryOptions [1][row] = btnPlay;
        aryOptions [2][row] = btnDelete;

        //Formats the GridBagLayout (Spaces are for formatting purposes)
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = row;
        layoutBackground.add(lblDeckName[row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 1;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("      "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx =2;
        gbc.gridy = row;
        layoutBackground.add(new JLabel (strSubjectName),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 3;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("                   "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 4;
        gbc.gridy = row;
        layoutBackground.add(new JLabel(strLineNumber2),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 5;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("             |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 6;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[0][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 7;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 8;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[1][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 9;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 10;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[2][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 11;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |"),gbc);




        //Creates an action event for the delete set button
        btnDelete.addActionListener((ActionEvent a) -> {
            //Finds the source of the button that was clicked
            String strSource = String.valueOf(a.getSource());
            String strSourceCut1 = strSource.substring(25,30); 

            //Finds the index of the button that was clicked
            String [] aryIndex = strSourceCut1.split(",");
            String strIndex = aryIndex[0];

            try {
                //Defines new file reader and buffered reader                   
                FileReader file_to_read2 = new FileReader(path);
                BufferedReader br2 = new BufferedReader(file_to_read2);

                //Finds the numerical index of the button that was clicked
                int intIndex = Integer.parseInt(strIndex)/16;

                //Creates a counter to count line numbers
                int counter = 0;

                while((br2.readLine()) != null) {

                    counter ++;
                    if(intIndex == 0) { //If the index is the first option the normal try/catch returns null pointer, so a new try/catch had to be created
                        try {
                            //Finds the name of the set based on what button was clicked
                            String chosenDeck2 = br2.readLine();
                            String [] aryDeleteDeck = chosenDeck2.split(",");
                            deleteDeck = aryDeleteDeck[0];

                            //Closes the buffered reader and file reader
                            br2.close();
                            file_to_read2.close();

                            //Creates the path to the file that needs to be deleted
                            Path p2 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
                            Files.delete(p2);

                        } catch (IOException e) {
                            JOptionPane.showMessageDialog(null, e);
                        }

                    } else if ( counter == intIndex) {
                        //Reads the deck name based on the button that was clicked
                        String chosenDeck2 = br2.readLine();

                        //Splits the deck name from the subject
                        String [] aryDeleteDeck = chosenDeck2.split(",");            
                        deleteDeck = aryDeleteDeck[0];

                        //Closes the buffered reader and file reader
                        br2.close();
                        file_to_read2.close();

                        //Gets the file that needs to be deleted
                        Path p1 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
                        Files.delete(p1);

                    }
                }
            }
            catch (HeadlessException | IOException | NumberFormatException e) {
                JOptionPane.showMessageDialog(null, e);
            }
        });

        //Creates an action event for the add words button
        btnAddWords.addActionListener((ActionEvent a) -> {
            //Finds the source of the button that was clicked
            String strSource = String.valueOf(a.getSource());
            String strSourceCut1 = strSource.substring(25,30);

            //Finds the index of the button that was clicked
            String [] aryIndex = strSourceCut1.split(",");
            String strIndex = aryIndex[0];

            try {
                //Creates a new file reader and buffered reader
                FileReader file_to_read3 = new FileReader(path);
                BufferedReader br3 = new BufferedReader(file_to_read3);

                //Finds the index value
                int intIndex = Integer.parseInt(strIndex)/16;

                //Creates a counter to count line numbers
                int counter = 0;

                while((br3.readLine()) != null) {
                    //Increases counter value by 1
                    counter ++;
                    if(intIndex == 0)
                    {
                        try {
                            //Reads the set and subject for the 
                            String chosenDeck2 = br3.readLine();

                            //Splits the subject from the set
                            String [] aryDeck = chosenDeck2.split(",");
                            chosenDeck = aryDeck[0];

                            //Closes the buffered reader and file reader
                            br3.close();
                            file_to_read3.close();



                        } catch (Exception e) {
                            JOptionPane.showMessageDialog(null, e);
                        }

                    } else if ( counter == intIndex) {
                        String chosenDeck2 = br3.readLine();

                        String [] aryDeck = chosenDeck2.split(",");
                        chosenDeck = aryDeck[0];

                        br3.close();
                        file_to_read3.close();  
                    }

                }
            }
            catch (Exception e) {
                JOptionPane.showMessageDialog(null, e);
            }
            //Opens the new words frame
            frmWords s = new frmWords(deckName, newXPoint, newYPoint, chosenDeck);
            s.setVisible(true);
        });
    }

    } catch (Exception e ) {
        JOptionPane.showMessageDialog(null, e);


    }

我发现的是,当我删除br1.close()时,流关闭错误停止,但我可以找到任何理由?没有什么可以使用那个读者,我可以看到。当我删除它时,我得到并且错误地说其他进程正在使用测试文件,我只能假设它是br1。

我知道这可能看起来很混乱,可能是因为它是草率的代码,但我真的很感激一些帮助。我是一名高中生。

谢谢:)

2 个答案:

答案 0 :(得分:0)

您可以使用Java 7中的closable功能:

 try ( FileReader file_to_read = new FileReader(path);
              BufferedReader br1 = new BufferedReader(file_to_read)){
            //Finds the line number to see the number of cards in each set
            lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
            lnr2.skip(Long.MAX_VALUE);
            strLineNumber2 = String.valueOf(lnr2.getLineNumber());
            lineNumber2 = Integer.parseInt(strLineNumber2);
        } catch (IOException | NumberFormatException e) {
            strLineNumber2 = "0";
        }

然后您不必关心以正确的顺序关闭您的流或文件。
此外,您可以使用libs来执行“readFile”工作,如apache commons或guava。

答案 1 :(得分:0)

当您构建嵌套的Readers时,例如,

    FileReader file_to_read = new FileReader(path);
    BufferedReader br1 = new BufferedReader(file_to_read);

,关闭外部也自动关闭内部。你不需要自己关闭内部的那个,如果你在关闭外部的那个之后尝试这样做,你会发现它已经关闭了。

最佳解决方案是仅关闭外部解决方案(而不是仅关闭内部的解决方法)。你可能甚至不需要保留对内部引用的引用 - 一个更典型的习语会像这样:

    BufferedReader br1 = new BufferedReader(new FileReader(path));

    try {
        // ... manipulate br1 ...
    } finally {
        br1.close();
        // no need to explicitly close the inner FileReader
    }

如果适合你的想法,你可以用try-with-resources形式写出来。

类似也适用于嵌套WriterInputStreamOutputStream s。