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
)。