HOWTO · Java
Java 中的属性文件
本文讨论 Java 中的属性文件。
本页内容
Java 的 Properties 类以键值对的形式保存应用程序配置,通常存储在扩展名为 .properties 的文件中。使用 setProperty() 添加字符串键和值,使用 store() 保存,使用 load() 读取,再用 getProperty() 获取单个设置。list() 方法则可显示已加载的条目,供检查使用。
使用 .properties 文件在 Java 教程 的文件 IO 与属性分组中讲解,Java 配置类指南都汇集在那里。
在 Java 属性文件中创建并设置值
属性文件每行包含一项。例如,version=1.1 和 projectName=PropertiesFileExample 是两个独立条目;以 # 或 ! 开头的行是注释。键值之间可以用 =、: 或空白分隔。键前的空白会被忽略,值中可以包含空格。使用 setProperty() 添加每一组键值,再用 store() 写入这些条目,并可附带一条注释。
运行以下示例:
本节中的代码以及显示的标签或输出仍为英文。
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
public class JavaExample {
public static void main(String[] args) throws IOException {
Path directory = Files.createTempDirectory("properties-demo-");
Path file = directory.resolve("myConfigs.properties");
Properties properties = new Properties();
properties.setProperty("version", "1.1");
properties.setProperty("projectName", "PropertiesFileExample");
properties.setProperty("date", "2021/12/27");
try (OutputStream output = Files.newOutputStream(file)) {
properties.store(output, "Application settings");
}
}
}
Files.newOutputStream() 会在文件不存在时创建文件;如果文件已存在,则会截断并覆盖其内容。文件的父目录必须已存在;此示例会先创建临时目录。即使写入失败,try-with-resources 也会关闭输出流。如果改用固定路径,请在打开文件前创建其父目录。除了条目,store() 还会写入注释和自动生成的时间戳,因此这些注释行会因运行时间不同而变化。使用 OutputStream 时,非拉丁字符会依照属性文件格式进行转义;使用 Writer 则可以明确指定字符编码。
如果代码使用 java.io,new FileOutputStream(path) 同样会在文件不存在时创建文件,并在文件已存在时截断其内容;它也要求父目录已经存在。与上面的输出流一样,使用 try-with-resources 关闭它。
从 Java 属性文件中获取属性
若要读取某项设置,请打开已保存的文件以供输入,在 Properties 对象上调用 load(),然后将所需的键传给 getProperty()。此示例在同一次运行中写入并读取文件,因此不依赖其他程序预先留下的文件。输入流也使用 try-with-resources,在加载完成后会关闭文件。
本节中的代码以及显示的标签或输出仍为英文。
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
public class JavaExample {
public static void main(String[] args) throws IOException {
Path directory = Files.createTempDirectory("properties-demo-");
Path file = directory.resolve("myConfigs.properties");
Properties saved = new Properties();
saved.setProperty("date", "2021/12/27");
try (OutputStream output = Files.newOutputStream(file)) {
saved.store(output, "Application settings");
}
Properties loaded = new Properties();
try (InputStream input = Files.newInputStream(file)) {
loaded.load(input);
}
String date = loaded.getProperty("date");
System.out.println(date == null ? "No date setting" : date);
}
}
如果键不存在,getProperty() 会返回 null,而不会抛出错误。若设置是可选的,请检查 null;也可以通过 getProperty("theme", "light") 提供备用值。文件不存在、路径不可读或发生其他文件访问问题,则属于不同情况:打开或加载文件时可能会引发 IOException。请在应用程序边界处理此异常并给出有用的提示,或交由调用方决定如何恢复。此示例在 main 上声明 IOException,以便清楚展示读取流程;实际应用通常会在能够提供上下文的位置捕获异常。
从 Java 属性文件中获取所有键和值
若要快速查看控制台内容,请加载文件,并将 System.out 传给 list()。下面的完整示例会先创建输入文件,再显示加载后的条目。示例还包含第二项设置,因此输出会展示多组键值对。
本节中的代码以及显示的标签或输出仍为英文。
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
public class JavaExample {
public static void main(String[] args) throws IOException {
Path directory = Files.createTempDirectory("properties-demo-");
Path file = directory.resolve("myConfigs.properties");
Properties saved = new Properties();
saved.setProperty("version", "1.1");
saved.setProperty("projectName", "PropertiesFileExample");
try (OutputStream output = Files.newOutputStream(file)) {
saved.store(output, "Application settings");
}
Properties loaded = new Properties();
try (InputStream input = Files.newInputStream(file)) {
loaded.load(input);
}
loaded.list(System.out);
}
}
list() 用于生成易读的诊断列表,不是通用的遍历 API。其显示格式和条目顺序都不是稳定的解析或比较格式。如果应用程序代码需要处理这些条目,请改为遍历 Properties 中的条目或键,并将每个值作为字符串处理。如果条目顺序或注释很重要,请以原始文件为准:保存属性用于存储配置数据,而 list() 仅显示当前已加载到内存中的值。