ZetCode

Java IOError 类

最后修改时间:2025 年 4 月 16 日

java.io.IOError 类表示无法恢复的严重 I/O 错误。它继承自 Error 类,当 I/O 操作发生灾难性故障时抛出。与 IOException 不同,它指示无法恢复的故障。

当 JVM 遇到严重的 I/O 问题,如磁盘故障或网络中断时,通常会抛出 IOError。它是一个未检查的异常,这意味着不需要在方法签名中声明。应用程序通常不应捕获此错误。

IOError 类概述

IOError 是一个简单的类,具有最少的方法。其主要目的是包装导致故障的底层 IOException。该类提供从 Error 继承的标准错误功能。

public class IOError extends Error {
    public IOError(Throwable cause);
    public Throwable getCause();
}

上面的代码显示了 IOError 的完整 API。构造函数接受一个 Throwable(通常是 IOException)作为原因。getCause 方法检索原始异常。

基本的 IOError 示例

此示例演示了在实际场景中可能如何抛出 IOError。我们模拟文件读取期间发生的灾难性磁盘故障。该错误会在调用堆栈中传播。

Main.java
import java.io.IOError;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try {
            readCriticalFile();
        } catch (IOError e) {
            System.err.println("Critical I/O failure occurred:");
            e.printStackTrace();
            System.exit(1);
        }
    }

    static void readCriticalFile() {
        try {
            // Simulate catastrophic I/O failure
            throw new IOException("Disk head crash - data unrecoverable");
        } catch (IOException e) {
            // Wrap in IOError to indicate unrecoverable state
            throw new IOError(e);
        }
    }
}

此示例显示了将 IOException 转换为 IOError 的典型模式。main 方法捕获错误并在顶层处理它。在实际应用程序中,此类错误通常需要终止进程。

处理文件操作中的 IOError

此示例演示了 IOError 在文件操作期间可能如何发生。我们创建一个读取配置文件的函数,并以不同的方式处理可恢复错误和不可恢复错误。

Main.java
import java.io.IOError;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Main {

    public static void main(String[] args) {
        try {
            String config = readConfigFile("config.cfg");
            System.out.println("Config loaded: " + config);
        } catch (IOError e) {
            System.err.println("FATAL: Cannot read critical config file");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Warning: Using default configuration");
        }
    }

    static String readConfigFile(String path) throws IOException {
        try {
            return new String(Files.readAllBytes(Paths.get(path)));
        } catch (IOException e) {
            if (isCriticalFailure(e)) {
                throw new IOError(e);
            }
            throw e;
        }
    }

    static boolean isCriticalFailure(IOException e) {
        // Check if error is truly unrecoverable
        return e.getMessage() != null 
            && e.getMessage().contains("Permission denied");
    }
}

此示例显示了差异化的错误处理。常规 I/O 问题抛出 IOException,而严重故障抛出 IOErrorisCriticalFailure 方法确定哪些错误是致命的。

网络操作中的 IOError

当面临无法恢复的故障时,网络操作也可能抛出 IOError。此示例模拟了需要 IOError 的网络连接故障。

Main.java
import java.io.IOError;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Main {

    public static void main(String[] args) {
        try {
            connectToServer("example.com", 8080);
        } catch (IOError e) {
            System.err.println("Network subsystem failure:");
            e.getCause().printStackTrace();
            System.exit(1);
        }
    }

    static void connectToServer(String host, int port) {
        try {
            // Simulate network hardware failure
            throw new IOException("Network adapter not functioning");
        } catch (IOException e) {
            throw new IOError(e);
        }
    }
}

此示例演示了与网络相关的 IOError 的用法。模拟的网络适配器故障被视为不可恢复。main 方法在退出前打印底层原因。

自定义 IOError 子类

为了更具体的错误处理,您可以创建自定义 IOError 子类。此示例显示了一个特定于磁盘故障的错误类,其中包含额外的诊断信息。

Main.java
import java.io.IOError;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try {
            accessStorageDevice();
        } catch (DiskFailureError e) {
            System.err.println("Disk failure on device: " + e.getDevice());
            System.err.println("Sector: " + e.getBadSector());
            e.printStackTrace();
        }
    }

    static void accessStorageDevice() {
        try {
            // Simulate disk failure
            throw new IOException("Sector 2048 unreadable");
        } catch (IOException e) {
            throw new DiskFailureError("/dev/sda", 2048, e);
        }
    }
}

class DiskFailureError extends IOError {
    private final String device;
    private final int badSector;

    public DiskFailureError(String device, int badSector, IOException cause) {
        super(cause);
        this.device = device;
        this.badSector = badSector;
    }

    public String getDevice() {
        return device;
    }

    public int getBadSector() {
        return badSector;
    }
}

此示例创建一个自定义 DiskFailureError 子类。它向标准 IOError 添加了设备和扇区信息。main 方法使用此额外信息进行更详细的错误报告。

资源加载中的 IOError

当故障无法恢复时,加载关键资源可能会抛出 IOError。此示例显示了使用适当错误处理的资源加载。

Main.java
import java.io.IOError;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Main {

    public static void main(String[] args) {
        try {
            loadCriticalResource("security.cert");
        } catch (IOError e) {
            System.err.println("Cannot load security certificate:");
            System.err.println(e.getCause().getMessage());
            System.exit(1);
        }
    }

    static void loadCriticalResource(String path) {
        try (InputStream is = Files.newInputStream(Paths.get(path))) {
            // Process the resource
            System.out.println("Resource loaded successfully");
        } catch (IOException e) {
            throw new IOError(e);
        }
    }
}

此示例演示了用于关键资源加载的 IOError 用法。安全证书对于应用程序至关重要,因此加载失败需要 IOError。try-with-resources 确保正确的流管理。

IOError 与 IOException

此示例将 IOError 与常规 IOException 处理进行了对比。它显示了在文件复制场景中每种类型的错误何时适用。

Main.java
import java.io.IOError;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {

    public static void main(String[] args) {
        try {
            copyFile("source.txt", "destination.txt");
        } catch (IOError e) {
            System.err.println("Fatal storage error during copy:");
            e.printStackTrace();
            System.exit(1);
        } catch (IOException e) {
            System.err.println("File copy failed, but retry possible:");
            e.printStackTrace();
        }
    }

    static void copyFile(String src, String dest) throws IOException {
        Path source = Paths.get(src);
        Path target = Paths.get(dest);
        
        try {
            Files.copy(source, target);
        } catch (IOException e) {
            if (isStorageFailure(e)) {
                throw new IOError(e);
            }
            throw e;
        }
    }

    static boolean isStorageFailure(IOException e) {
        return e.getMessage() != null 
            && (e.getMessage().contains("device error")
                || e.getMessage().contains("sector not found"));
    }
}

此示例显示了文件操作中的差异化错误处理。常规文件问题抛出 IOException,而硬件故障抛出 IOErrorisStorageFailure 方法有助于确定要使用的错误类型。

来源

Java IOError 类文档

在本文中,我们介绍了 Java IOError 类的基本方面。理解何时使用 IOError 与 IOException 对于在处理 I/O 操作的 Java 应用程序中进行适当的错误处理至关重要。

作者

我叫 Jan Bodnar,是一位经验丰富的程序员。我于 2007 年开始撰写编程文章,至今已撰写了 1,400 多篇文章和八本电子书。凭借超过八年的教学经验,我致力于分享我的知识,帮助他人掌握编程概念。

列出所有Java教程