ZetCode

Java FileNotFoundException 类

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

java.io.FileNotFoundException 是一个受检异常,当指定路径名的文件不存在时抛出。 它也会在文件存在但由于权限问题无法打开进行读取或写入时发生。

这个异常继承自 IOException,是 Java I/O 异常层次结构的一部分。 作为一个受检异常,它必须被捕获或在方法签名中声明。 它提供了关于失败的文件操作的详细信息。

FileNotFoundException 类概述

FileNotFoundException 指示定位或打开文件失败。 异常消息通常包括有问题的文件路径。 构造函数允许创建带有自定义消息或原因的异常。

public class FileNotFoundException extends IOException {
    public FileNotFoundException();
    public FileNotFoundException(String s);
}

上面的代码显示了 FileNotFoundException 的简单结构。 它提供了两个构造函数 - 一个没有参数,一个接受详细消息。 该消息有助于识别无法访问的特定文件。

基本 FileNotFoundException 示例

此示例演示了 FileNotFoundException 发生的最常见场景 - 尝试读取不存在的文件。 异常在其消息中提供了关于缺失文件的信息。

Main.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Main {

    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("nonexistent.txt");
        } catch (FileNotFoundException e) {
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

运行时,此代码尝试打开一个不存在的文件。 异常处理程序捕获 FileNotFoundException 并打印其消息。 堆栈跟踪显示了异常在代码中发生的位置。 在处理文件操作时,始终处理此异常。

首先检查文件是否存在

一个常见的做法是在尝试打开文件之前检查文件是否存在。 这可以在某些情况下防止 FileNotFoundException。 但是,在检查和打开之间仍然可能发生竞争条件。

Main.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Main {

    public static void main(String[] args) {
        String filename = "data.txt";
        File file = new File(filename);
        
        if (!file.exists()) {
            System.out.println("File " + filename + " does not exist");
            return;
        }
        
        try {
            FileInputStream fis = new FileInputStream(file);
            System.out.println("File opened successfully");
            fis.close();
        } catch (FileNotFoundException e) {
            System.out.println("File disappeared after checking: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

此示例首先使用 File.exists 检查文件是否存在。 如果不存在,它会避免尝试打开它。 但是,该文件可能在检查和打开操作之间被删除。 因此,为了代码的健壮性,仍然需要异常处理。

权限相关的 FileNotFoundException

当缺少访问现有文件的权限时,也可能发生 FileNotFoundException。 此示例演示了尝试读取没有适当读取权限的文件。

Main.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Main {

    public static void main(String[] args) {
        try {
            // Attempt to open a protected system file
            FileInputStream fis = new FileInputStream("/etc/shadow");
            fis.close();
        } catch (FileNotFoundException e) {
            System.out.println("Access denied: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在类 Unix 系统上,/etc/shadow 通常只能由 root 用户读取。 当在没有足够权限的情况下运行时,此代码会抛出 FileNotFoundException。 异常消息指示权限被拒绝。 在处理文件时,始终检查存在性和权限。

带有详细消息的 FileNotFoundException

我们可以创建带有特定消息的自定义 FileNotFoundException 实例。 当实现需要向调用者提供详细错误信息的文件操作时,这非常有用。

Main.java
import java.io.FileNotFoundException;

public class Main {

    public static void main(String[] args) {
        String filename = "config.xml";
        
        try {
            openConfigFile(filename);
        } catch (FileNotFoundException e) {
            System.out.println("Configuration error: " + e.getMessage());
        }
    }
    
    public static void openConfigFile(String path) throws FileNotFoundException {
        if (!path.endsWith(".xml")) {
            throw new FileNotFoundException("Invalid config file format: " + path);
        }
        // Actual file opening logic would go here
        throw new FileNotFoundException("Config file not found: " + path);
    }
}

此示例显示了如何使用自定义消息抛出 FileNotFoundException。 openConfigFile 方法在尝试打开文件之前验证文件格式。 自定义消息有助于识别文件访问问题的确切性质。

在文件复制中处理 FileNotFoundException

文件操作通常涉及多个步骤,其中可能发生 FileNotFoundException。 此示例演示了文件复制操作中的适当异常处理。

Main.java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        String source = "source.txt";
        String destination = "destination.txt";
        
        try {
            copyFile(source, destination);
            System.out.println("File copied successfully");
        } catch (FileNotFoundException e) {
            System.out.println("File error: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("I/O error: " + e.getMessage());
        }
    }
    
    public static void copyFile(String src, String dest) 
            throws FileNotFoundException, IOException {
        try (FileInputStream fis = new FileInputStream(src);
             FileOutputStream fos = new FileOutputStream(dest)) {
            
            byte[] buffer = new byte[1024];
            int length;
            
            while ((length = fis.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
        }
    }
}

如果源文件不存在或无法创建目标文件,则此文件复制操作可能会抛出 FileNotFoundException。 try-with-resources 语句确保正确关闭流。 不同类型的异常被分别处理,以提供适当的错误消息。

FileNotFoundException 在目录操作中

尝试像打开文件一样打开目录也会抛出 FileNotFoundException。 此示例演示了这种情况,并展示了如何区分文件和目录。

Main.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Main {

    public static void main(String[] args) {
        String path = "/tmp"; // A directory path
        
        try {
            File file = new File(path);
            
            if (file.isDirectory()) {
                System.out.println(path + " is a directory, not a file");
                return;
            }
            
            FileInputStream fis = new FileInputStream(file);
            fis.close();
        } catch (FileNotFoundException e) {
            System.out.println("File access error: " + e.getMessage());
        }
    }
}

此代码首先使用 isDirectory 检查路径是否指向目录。 如果没有此检查,尝试打开目录将抛出 FileNotFoundException。 在执行文件操作之前,始终验证路径的性质。

来源

Java FileNotFoundException 类文档

在本文中,我们探讨了 Java 中发生 FileNotFoundException 的各种场景。 正确处理此异常对于构建健壮的文件处理代码至关重要。 在处理文件时,始终考虑文件是否存在、权限和类型。

作者

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

列出所有Java教程