什么时候可能抛出 IOError?

When might an IOError be thrown?

我从未见过抛出 IOError 的情况。文档关于 IOError 的唯一说明是:

Thrown when a serious I/O error has occurred.

没有任何子类或任何其他明显的东西。

有没有在 java 中抛出 IOError 的情况?可能是什么原因造成的?

(不要与 IOException 混淆——IOException 在很多情况下都会被抛出,并且很常用;我知道这一点。我想知道 less常见 IOError).

IOError 很少使用。我认为它的主要用例在 java.io.Console#readLine()readPassword() 中,默认情况下它们不会抛出 IOExeption(但将其包装)以发出 I/O 问题信号。

我猜这样做的动机是,他们很少不想声明已检查的异常。当终端出现问题时可能会发生这种情况 - 现在您不再有串行线路,只会在严重的系统条件下发生,例如 运行 内存或句柄不足。

Console, Path#toAbsolutePath, and Path#toUri 声明要抛出此特定异常。当然,这是一个文件事实,而不是一个实际的声明;因为 Error 是一个运行时异常,所以在签名中声明它被抛出是没有意义的。

从代码中看,Console#readLineConsole#readPassword 捕获一个 IOException 通过其正常操作产生的结果, 然后 传播IOError.

本质上,IOError 代表底层文件系统的严重故障,或访问某些将 Java 绑定到文件系统的资源。它不会 经常 抛出,但如果文件系统内发生严重的事情,它有可能被抛出。

要查找的一个官方资源是 Java Bug Database,您可以在其中使用搜索关键字搜索涉及 IOError 的错误。这可以显示一些涉及此错误的真实案例。

直接引用此错误的事件(至少这是我能够找到的)发生在 JDK-6347312 中,它处理 Console.readLine().

JDK中的用法也很少。它很可能用于发出调用者不应该处理的类似 "critical" IOException 的异常信号(与其他运行时异常一样)。

IOError 是运行时异常,属于错误类别,是未经检查的异常。对我来说,当您使用 JVM 对底层 OS 系统调用的 JNI/native 调用与系统交互时,这似乎会发生。这可能是为了获得对 IO 设备(存储、键盘、显示器、网络等)的访问权限。但是我几乎没有看到它在 Java API docs.Most 中使用,可能是因为实现者希望将对底层系统的依赖保持在最低限度。

此外,RedHat JBoss Wildfly 域管理库明确地为它们的 ConsoleWrapper 接口抛出 IOError。到目前为止,我看到的唯一实现是 JavaConsole class.

来源:

/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2012, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.domain.management.security.adduser;

import java.io.IOError;
import java.util.IllegalFormatException;

/**
 * Wrap the console commands
 *
 * @author <a href="mailto:flemming.harms@gmail.com">Flemming Harms</a>
 */
public interface ConsoleWrapper<T> {

    /**
     * Writes a formatted string to this console's output stream using
     * the specified format string and arguments.
     * see <a href="../util/Formatter.html#syntax">Format string syntax</a>
     * @param fmt
     * @param args
     */
    T format(String fmt, Object ...args) throws IllegalFormatException;

    /**
     * A convenience method to write a formatted string to this console's
     * output stream using the specified format string and arguments.
     *
     * @param format
     * @param args
     * @throws IllegalStateException
     */
    void printf(String format, Object ... args) throws IllegalFormatException;

    /**
     * Provides a formatted prompt, then reads a single line of text from the
     * console.
     *
     * @param fmt
     * @param args
     * @return A string containing the line read from the console, not
     *          including any line-termination characters, or <tt>null</tt>
     *          if an end of stream has been reached.
     * @throws IOError
     */
    String readLine(String fmt, Object ... args) throws IOError;

    /**
     * Provides a formatted prompt, then reads a password or passphrase from
     * the console with echoing disabled.
     *
     * @param fmt
     * @param args
     * @return  A character array containing the password or passphrase read
     *          from the console.
     * @throws IOError
     */
    char[] readPassword(String fmt, Object ... args) throws IllegalFormatException, IOError;

    /**
     *  Return the console object
     *
     * @return Return the console object
     */
    T getConsole();
}

Is there ever a case when IOError would be thrown in java?

import java.io.IOError;

public class Test {

    public static void main(String[] args) {
        throw new IOError(new Exception());
    }

}

将导致

Exception in thread "main" java.io.IOError: java.lang.Exception
    at test.Test.main(Test.java:13)
Caused by: java.lang.Exception
    ... 1 more
Java Result: 1

我相信你期待一个更有可能发生的案例。

例如,当尝试从输入流已关闭的控制台读取时,将抛出 IOError

你可以试试运行这个片段

import java.io.*;

public class Test {

    public static void main(String[] s) {
        Console con = System.console();
        try {
            InputStreamReader reader = new InputStreamReader(System.in);
            reader.close();
            String st = con.readLine("%s", "Enter a line");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IOError error) {
            error.printStackTrace();
        }
    }
}

这将导致

java.io.IOError: java.io.IOException: Stream Closed
    at java.io.Console.readLine(Console.java:254)
    at Test.main(Test.java:10)
Caused by: java.io.IOException: Stream Closed
    at java.io.FileInputStream.readBytes(Native Method)
    at java.io.FileInputStream.read(FileInputStream.java:246)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.Console$LineReader.read(Console.java:437)
    at java.io.Console.readline(Console.java:376)
    at java.io.Console.readLine(Console.java:250)
    ... 1 more

这是来自 Oracle 的 Mark Reinhold 的解释:

The new IOError class was defined in combination with the new java.io.Console class. It’s for use in situations where an unrecoverable I/O error occurs and the most appropriate response is to terminate the program rather than attempt to handle the exception.

The IOError class, along with many other enhancements, will be documented in the forthcoming Mustang maintenance review in the JCP.

http://cafe.elharo.com/blogroll/undocumented-changes-in-java-6-mustang-ioerror/

我不确定为什么这么多人说错误是运行时异常。他们不是。简单看一下API。 ErrorException 属于不同的 Throwable 类别。 RuntimeExceptionException 的子类型。

简单来说,Error(及其子类型)用于表示合理的应用程序不应该试图捕获的严重问题。另一方面,Exception 用于指示 合理的应用程序 可能 想要捕获的条件 。它并没有说你 必须 。它声明 MIGHT 的原因是因为 RuntimeExceptionException 的子类型,任何导致运行时异常的条件都应该在开发期间(很可能)得到修复,以便在部署应用程序时,应该不需要处理这些类型的条件。但是,可以选择继续为它们使用 catch 子句。

底线:Error 不是 RuntimeException。这么说是完全错误的。