Java IO 异常处理与 Properties 使用详解

阿麦
阿麦
发布时间:2026-10-15 | 4人浏览过
原创

本文深入解析Java IO流在开发中的异常处理机制,对比不同JDK版本的语法差异,避免手动关闭资源引发的隐患。同时结合Properties持久化属性集类,演示如何通过键值对结构读取外部配置文件,提供从安全写入到配置管理的完整实战方案。

JDK 7之前:传统 try-catch-finally 模式

在实际项目研发中,直接将异常抛出给上层并不总是最佳选择,通常需要进行捕获处理以防止程序崩溃。传统的做法是使用 try-catch-finally 代码块。核心逻辑是:在 finally 块中判断资源是否为空并执行关闭操作,确保无论发生何种情况都能释放系统资源。

操作步骤:

  1. 定义变量范围:FileWriter 实例需在 try 外部声明,以便 finally 块访问。
  2. 尝试初始化与写入:在 try 中创建流对象并执行写操作。
  3. 捕获异常:在 catch (IOException e) 中记录堆栈信息。
  4. 安全关闭:在 finally 再次包装一次 try-catch 来判断并关闭流(防止关闭时再次抛出异常导致掩盖原异常)。
public class HandleException1 {
    public static void main(String[] args) {
        // 1. 声明变量,作用域需包含 finally
        FileWriter fw = null;
        try {
            // 2. 创建流并写出数据
            fw = new FileWriter("fw.txt");
            fw.write("三分归元气"); 
        } catch (IOException e) {
            // 3. 捕获并处理读写过程中的异常
            e.printStackTrace();
        } finally {
            // 4. 确保资源释放
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

JDK 7 的改进:try-with-resources 语句

JDK 7 引入了自动资源管理机制(Try-With-Resources)。实现了 AutoCloseable 接口的对象(如各种 Stream)可以直接在 try() 括号内声明。优势:JVM 会自动调用这些对象的 close() 方法,无需编写繁琐的 finally 块,代码更简洁且不易遗漏关闭。

第1步:在 try 括号中声明流

将需要自动关闭的资源对象实例化放在 try( ... ) 中。若有多个资源,以分号隔开。注意,这里声明的对象具有“最终性”(effectively final)。

第2步:执行数据操作

在 try{ } 内部进行读写字节或字符的操作。

public class HandleException2 {
    public static void main(String[] args) {
        // JDK7:直接在try头中创建流对象
        try (FileWriter fw = new FileWriter("fw.txt");) {
            // 写出数据
            fw.write("三分归元气"); 
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 退出try块时,fw已自动关闭
    }
}

JDK 9 的进一步优化

JDK 9 进一步放宽了限制。如果资源对象已经是 final 修饰的变量,或者在 try 之前已经被赋值为非空的局部变量,那么可以直接将该变量名放入 try 括号中,而无需重新声明创建。

应用场景对比

  • JDK 7/8:必须写成 try (Resource r = resource) 形式,创建新引用。
  • JDK 9+:允许直接传入变量名 try (resource)。这极大简化了代码冗余。

综合读取演示(支持 JDK 9+)

利用此特性,我们可以同时管理输入和输出流。注意变量类型判定,普通变量不能直接使用,需符合上述规则。

public class TryDemo {
    public static void main(String[] args) throws IOException {
        // 创建源和目标对象
        final FileReader fr = new FileReader("in.txt");   // final 关键字修饰
        FileWriter fw = new FileWriter("out.txt");       // JDK9可直接引入

        // JDK9方式:直接在括号内引入变量
        try (fr; fw) {
            int b;
            // 边读边写
            while ((b = fr.read()) != -1) {
                fw.write(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Properties 属性集的使用

在处理配置文件时,我们常遇到大量的 key=value 格式数据。Java 提供了 java.util.Properties 类来专门处理此类场景。它继承自 Hashtable,但只接受字符串类型的 Key 和 Value。

基础内存操作

通过 setProperty 存入数据,getProperty 获取数据。适合简单的内存键值缓存。

public class ProDemo {
    public static void main(String[] args) {
        // 1. 实例化对象
        Properties properties = new Properties();
        
        // 2. 添加键值对 (Key/Value 必须是 String)
        properties.setProperty("filename", "a.txt");
        properties.setProperty("length", "209385038");
        properties.setProperty("location", "D:\\a.txt");
        
        // 3. 根据键获取值
        System.out.println(properties.getProperty("filename"));
        
        // 4. 遍历所有键
        Set<String> keys = properties.stringPropertyNames();
        for (String key : keys) {
            System.out.println(key + " -- " + properties.getProperty(key));
        }
    }
}

持久化加载:load() 方法

实际项目中,配置通常存在于外部文本文件中(如 .properties 文件)。此时需使用 load(InputStream inStream) 方法将外部数据读入集合。

前提条件: 外部文件格式必须符合 key=value 规范,且每行一组。

public class ProDemo2 {
    public static void main(String[] args) {
        try {
            Properties pro = new Properties();
            // 使用字节输入流关联本地文件
            // 假设当前目录下存在 read.txt
            pro.load(new FileInputStream("read.txt"));
            
            Set<String> strings = pro.stringPropertyNames();
            for (String key : strings) {
                System.out.println(key + " -- " + pro.getProperty(key));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

以上就是关于 Java IO 异常安全处理及 Properties 配置集读取的详细内容。更多关于 Java 高级特性的学习资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表