Java--IO流详解(下)--相互转换(含Properties详解)
目录
一、字符流与字节流之间的桥梁
1. InputStreamReader
构造方法
例子:
2. OutputStreamWriter
构造方法
例子:
二、Properties
Properties 类概述
例子:
连接数据库示例:
数据库配置文件(例子db.properties)
连接代码演示:
注释:
Properties提供的常用方法
加载与保存
属性操作
其他
三、Random 类中的常用方法
前面介绍了这么多IO流字节流和字符流的定义和方法,现在有必要说一下这两者之间互相转化的问题,即“桥梁”。
一、字符流与字节流之间的桥梁
1. InputStreamReader
 
InputStreamReader 是一个 从字节流到字符流的转换器。它将字节输入流(InputStream)转换为字符输入流(Reader),并允许指定字符编码。
构造方法
InputStreamReader(InputStream in); // 使用默认字符编码
InputStreamReader(InputStream in, String charsetName); // 指定字符编码
InputStreamReader(InputStream in, Charset charset); // 指定字符编码 
例子:
try (InputStream inputStream = new FileInputStream("example.txt");
     Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
    int c;
    while ((c = reader.read()) != -1) {
        System.out.print((char) c);
    }
} catch (IOException e) {
    e.printStackTrace();
} 
2. OutputStreamWriter
 
OutputStreamWriter 是一个 从字符流到字节流的转换器。它将字符输出流(Writer)转换为字节输出流(OutputStream),并允许指定字符编码。
构造方法
OutputStreamWriter(OutputStream out); // 使用默认字符编码
OutputStreamWriter(OutputStream out, String charsetName); // 指定字符编码
OutputStreamWriter(OutputStream out, Charset charset); // 指定字符编码 
例子:
try (OutputStream outputStream = new FileOutputStream("example.txt");
     Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) {
    writer.write("Hello, World!");
    writer.flush();
} catch (IOException e) {
    e.printStackTrace();
} 
 
注意:写入和读取的编码要相同才可以成功转换。
二、Properties
Properties 类概述
Properties类是Java中用于处理键值对数据的工具类,主要用于加载和管理配置文件。(如.properties文件)。它继承自Hashtable,因此具有线程安全性,同时只能存储字符串类型的键和值,同时支持持久化,即:Properties可以保存到流中(如文件),也可以从流中加载。
例子:
使用Properties类加载和解析配置文件
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropTest6 {
    public static void main(String[] args) {
        // 创建一个Properties对象,用于存储键值对数据
        Properties prop = new Properties();
        InputStream in = null; // 定义一个InputStream变量,用于加载配置文件
        try {
            // 使用ClassLoader加载资源文件
            // 这里加载的是位于类路径下的names.properties文件
            // 类路径通常是src目录,打包后是JAR文件的根目录
            in = PropTest6.class.getClassLoader().getResourceAsStream("names.properties");
            // 检查输入流是否为null,避免加载失败时抛出异常
            if (in == null) {
                throw new IllegalArgumentException("Resource file not found: names.properties");
            }
            // 从输入流中加载数据到Properties对象中
            // load()方法会解析输入流中的内容,并将其存储为键值对
            prop.load(in);
            // 打印加载的配置信息
            // Properties类重写了toString()方法,可以直接打印其内容
            System.out.println(prop);
        } catch (Exception e) {
            // 捕获加载过程中可能发生的异常,例如文件未找到或格式错误
            e.printStackTrace();
        } finally {
            // 在finally块中关闭InputStream资源,确保不会发生内存泄漏
            if (in != null) {
                try {
                    in.close(); // 关闭输入流
                } catch (IOException e) {
                    // 捕获关闭流时可能发生的异常
                    e.printStackTrace();
                }
            }
        }
    }
} 
这个例子展示了如何使用Properties类加载和解析配置文件(.properties文件),并将其内容存储到Properties对象中。这种模式在实际开发中非常常见,主要用于以下几种场景:
其中最常用的就是数据库的连接:
数据库的连接信息(如URL、用户名、密码)通常存储在配置文件中,而不是硬编码到代码中。通过Properties类加载配置文件,可以在运行时动态获取这些信息,便于维护和更新。
连接数据库示例:
数据库配置文件(例子db.properties)
 
db.url=jdbc:mysql://localhost:3306/mydatabase
db.username=root
db.password=123456 
连接代码演示:
Properties prop = new Properties();
InputStream in = getClassLoader().getResourceAsStream("db.properties");
prop.load(in);
String dbUrl = prop.getProperty("db.url");
String dbUsername = prop.getProperty("db.username");
String dbPassword = prop.getProperty("db.password");
// 使用这些信息连接数据库 
通过Properties实体类prop的调用就可以获取连接数据库的关键信息。
注释:
类名.class是反射获取 Java 类对应的Class对象的类信息。getClassLoader()是Class对象的方法,用于获取加载当前类的类加载器。getResourceAsStream()是ClassLoader和Class提供的方法,可将类路径下的资源文件以输入流形式获取,便于读取资源内容。
 Properties提供的常用方法
 
加载与保存
load(InputStream inStream):从输入流加载属性,用于读取配置文件。load(Reader reader):从字符输入流加载属性。store(OutputStream out, String comments):把属性存到输出流,可加注释。store(Writer writer, String comments):将属性存到字符输出流。属性操作
getProperty(String key):根据键获取属性值。getProperty(String key, String defaultValue):获取属性值,无则返回默认值。setProperty(String key, String value):设置属性的键值对。其他
stringPropertyNames():返回所有键的集合。list(PrintStream out):把属性列表打印到指定输出流。
 通过Properties的性质,就可以实现动态部署而实现在游戏服务器需要更新时不停服。
假设有一个运行中的项目,它依赖于某个数据库库(如MySQL)。现在,希望将数据库切换到另一个库(如PostgreSQL),而不需要停服(因为重要信息并不是直接写在代码中的,而是通过Properties获取的),只需要修改.properties配置文件即可。
三、Random 类中的常用方法
 
Random():无参构造方法,使用系统当前时间作为种子创建随机数生成器。
Random(long seed):使用指定的种子值创建随机数生成器,相同种子生成相同的随机数序列。
nextInt():生成一个范围在-2^31到2^31 - 1的随机整数。
nextInt(int n):生成一个范围在[0, n)的随机整数。
nextDouble():生成一个范围在[0.0, 1.0)的随机双精度浮点数。
nextFloat():生成一个范围在[0.0, 1.0)的随机单精度浮点数。
nextLong():生成一个随机的长整数。
nextBoolean():生成一个随机布尔值(true或false)。
