【问题标题】:Java io handle is invalid exceptionJava io 句柄无效异常
【发布时间】:2012-06-08 21:09:54
【问题描述】:

我有一个使用 readPassword() 从控制台读取的函数。在一个程序迭代中多次调用此函数。但是,一旦到达 readPassword() 行,我就会不断收到 java io 异常。我注意到当我从 finally 子句中删除 close() 语句时,这个错误消失了。为什么会发生这种情况,我应该何时正确关闭阅读器?

public void Func()
{
        Console console = System.console();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        if (console == null)
            System.out.println("Error!");

        try 
        {
           char[] pwd = console.readPassword();
           String password = new String(pwd);
           System.out.println("PW: " + password);

           String input = reader.readLine();
           System.out.println("UserNm: " + input);
        } catch (IOException e) {
            System.out.println("IO EXCEPTION");
        } finally {
            if (reader != null)
            {
                try
                {
                    reader.close();
                }
                catch (IOException e)
                {
                    System.out.println("error");
                }
            }
        }
        return null;
}

提前感谢您的帮助!

【问题讨论】:

  • 异常消息在调试时非常有用。如:e.printStackTrace();
  • 感谢您的建议 :) 我会定期在我的实际代码中打印出堆栈跟踪。这只是一个存根。

标签: java io bufferedreader


【解决方案1】:

只有一个控制台,也只有一个System.in。如果您关闭它,那么您将无法再读取它!你不需要关闭那个BufferedReader,你也不应该。整个finally 块可以而且应该消失。

仔细阅读后,我什至不明白您为什么要创建 BufferedReader 首先——它似乎没有任何功能。只需删除所有处理它的代码!

【讨论】:

  • 即使每次调用该函数时我再次访问 System.console() ?这对我来说可能是不好的做法。如果我不关闭它,我可以依靠垃圾收集来为我处理它吗?
  • 垃圾回收不会关闭它,因为它不应该被关闭,这是我的观点。您可以随意调用 System.console() 多次而无需担心。
  • 很抱歉。我重新编辑了我原来的帖子。我使用 BufferedReader 读取用户名和控制台读取密码,因为控制台可以访问方便的 readPassword() 函数。
【解决方案2】:

这里不需要任何阅读器,只需使用 Console 实例即可。

public String Func() {
        Console console = System.console();
        if (console == null)
            throw new IllegalStateException("No console available");

        try {
           String username = console.readLine("Username: ");
           String pwd = new String(console.readPassword("Password: "));
           return pwd;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
}

使用您的问题编辑进行编辑。只需使用 Console 类,它可以读/写,您不需要任何读/写器。

【讨论】:

    【解决方案3】:

    改用 java.util.Scanner 之类的东西,正如其他人所说,不要担心尝试关闭 system.in。

    干净多了:

    Scanner in = new Scanner(System.in);
    String password  = in.nextLine(); 
    String username  = in.nextLine();
    

    无需整理/异常处理。

    【讨论】:

    • @alex 的答案更好,因为 readPassword 位。不将其存储为字符串并禁止输出文本
    【解决方案4】:

    您不应关闭您的Console。保持打开状态,直到您的程序不再需要读取它为止。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多