如何读取Properties文件中重复键的最后一个对应值?
嘿,我懂你现在的困扰——合并后的mail.properties里有重复的键,而ResourceBundle默认只会取第一个出现的值,但你需要的是最后那条对应的内容对吧?别担心,这里有两个实用的方案帮你解决:
方案1:直接使用
java.util.Properties加载(推荐) Properties类的load()方法天生就支持后面的键值对覆盖前面的,完全符合你的需求,而且实现起来最简单:
import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class LoadLastPropertyValue { public static void main(String[] args) { Properties mailProps = new Properties(); try (InputStream inputStream = new FileInputStream("path/to/your/mail.properties")) { // 加载文件时自动用最后出现的键值覆盖之前的 mailProps.load(inputStream); // 获取最终的对应值 String finalMailBody = mailProps.getProperty("mail.body"); // 得到 "body3" String finalMailSubject = mailProps.getProperty("mail.subject"); // 得到 "Reminder" System.out.println("最终邮件正文:" + finalMailBody); System.out.println("最终邮件主题:" + finalMailSubject); } catch (IOException e) { e.printStackTrace(); } } }
方案2:自定义
ResourceBundle.Control(如果必须用ResourceBundle) 如果你的项目架构必须依赖ResourceBundle,可以自定义一个Control类,内部用Properties处理重复键,再包装成ResourceBundle返回:
首先定义自定义Control:
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.ResourceBundle; public class LastValueResourceBundleControl extends ResourceBundle.Control { @Override public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { String bundleName = toBundleName(baseName, locale); String resourceName = toResourceName(bundleName, "properties"); try (InputStream inputStream = loader.getResourceAsStream(resourceName)) { if (inputStream != null) { Properties props = new Properties(); props.load(inputStream); // 用Properties处理重复键,自动覆盖 // 将处理后的Properties转为PropertyResourceBundle return new PropertyResourceBundle(new ByteArrayInputStream(props.toString().getBytes())); } } // fallback到默认实现 return super.newBundle(baseName, locale, format, loader, reload); } }
然后使用这个Control加载ResourceBundle:
import java.util.Locale; import java.util.ResourceBundle; public class ResourceBundleDemo { public static void main(String[] args) { ResourceBundle mailBundle = ResourceBundle.getBundle("mail", Locale.getDefault(), new LastValueResourceBundleControl()); String finalMailBody = mailBundle.getString("mail.body"); // "body3" String finalMailSubject = mailBundle.getString("mail.subject"); // "Reminder" System.out.println("最终邮件正文:" + finalMailBody); System.out.println("最终邮件主题:" + finalMailSubject); } }
补充说明
为什么ResourceBundle默认不行?因为它的默认实现在读取properties文件时,遇到重复键会直接忽略后续的条目,只保留第一个出现的值;而Properties类则正好相反,会用后续的新值覆盖旧值,这也是我们能利用它解决问题的核心原因。
内容的提问来源于stack exchange,提问作者ecdhe
相关产品推荐
相关产品推荐

