gpt4 book ai didi

没有 RessourceBundle 的 Java i18n

转载 作者:行者123 更新时间:2023-11-30 09:30:06 25 4
gpt4 key购买 nike

我正在尝试从我的 BuildPath 中获取 i18n 属性文件。如果您尝试获取 PropertiesFileResourceBundle.getBundle 将抛出 java.util.MissingResourceException。有没有一种方法可以从 BuildPath 外部加载 i18n 文件,但仍然可以轻松检测您的语言环境?

编辑:

这是我在 Paweł Dyda 的帮助下创建的解决方案.也许有人会需要它。可能会有一些改进,但它有效 ;)

import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle.Control;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;

public class GlobalConfigurationProvider {

Logger logger = Logger.getLogger(GlobalConfigurationProvider.class);

private static GlobalConfigurationProvider instance;

PropertiesConfiguration i18n;


private GlobalConfigurationProvider() {
String path = GlobalConfigurationProvider.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = "";
try {
decodedPath = URLDecoder.decode(path, "UTF-8");
// This ugly thing is needed to get the correct
// Path
File f = new File(decodedPath);
f = f.getParentFile().getParentFile();
decodedPath = f.getAbsolutePath();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
this.logger.error("Failed to decode the Jar path", e);
}
this.logger.debug("The Path of the jar is: " + decodedPath);

String configFolder = FilenameUtils.concat(decodedPath, "cfg");
String i18nFolder = FilenameUtils.concat(configFolder, "i18n");
File i18nFile = null;
try {
i18nFile = this.getFileForLocation(new File(i18nFolder), Locale.getDefault());
} catch (FileNotFoundException e) {
e.printStackTrace();
this.logger.error("Can't find the LocaleFile", e);
}
if (!i18nFile.exists()) {
// If this can't be found something is wrong
i18nFile = new File(i18nFolder, "eng.i18n");
if (!i18nFile.exists()) {
this.logger.error("Can't find the i18n File at the Location: " + i18nFile.getAbsolutePath());
}
}

this.logger.debug("The Path to the i18n File is: " + i18nFile);

try {
this.i18n = new PropertiesConfiguration(i18nFile);
} catch (ConfigurationException e) {
this.logger.error("Couldn't Initialize the i18nPropertiesFile", e);
}
}

private File getFileForLocation(File i18nFolder, Locale locale) throws FileNotFoundException {
Control control = Control.getControl(Control.FORMAT_DEFAULT);
List<Locale> locales = control.getCandidateLocales(this.getBaseName(), locale);
File f = null;
for (Locale l : locales) {
String i18nBundleName = control.toBundleName(this.getBaseName(), l);
String i18nFileName = control.toResourceName(i18nBundleName, "properties");
f = new File(i18nFolder, i18nFileName);
this.logger.debug("Looking for the i18n File at: " + f);
if (f.exists()) {
return f;
}
}
// Last try for a File that should exist
if (!locale.equals(Locale.US)) {
return this.getFileForLocation(i18nFolder, Locale.US);
}
throw new FileNotFoundException("Can't find any i18n Files in the Folder " + i18nFolder.getAbsolutePath());
}

private String getBaseName() {
// TODO: Get this from the Settings later
return "messages";
}

public static GlobalConfigurationProvider getInstance() {
if (GlobalConfigurationProvider.instance == null) {
GlobalConfigurationProvider.instance = new GlobalConfigurationProvider();
}
return GlobalConfigurationProvider.instance;
}

public String getI18nString(String key) {
try {
return this.i18n.getString(key);
} catch (MissingResourceException e) {
return '!' + key + '!';
}
}

}

最佳答案

当然有办法做到这一点。无论如何,我相信您的问题是您尝试加载的资源路径错误。

尽管如此,您肯定正在寻找使用区域设置回退机制来加载非常具体的资源的方法。可以办到。你可能想看看 ResourceBundle.Control类(class)。例如,您可以获得后备语言环境列表:

Control control = Control.getControl(Control.FORMAT_DEFAULT);
List<Locale> locales = control.getCandidateLocales("messages",
Locale.forLanguageTag("zh-TW"));

从那里,您实际上可以创建您要查找的资源文件的名称:

for (Locale locale : locales) {
String bundleName = control.toBundleName("messages", locale);
String resourceName = control.toResourceName(bundleName, "properties");
// break if resource under given name exist
}

然后,您需要以某种方式加载资源 - 您可能需要使用 ClassLoader's getResourceAsStream(String)为您打开 InputStream。最后一步实际上可以使用流作为 PropertyResourceBundle 的输入:

ResourceBundle bundle = new PropertyResourceBundle(inputStream);

您也可以传递 Reader而不是 InputStream,它至少有一个优点 - 您实际上可以允许将属性文件编码为 UTF-8,而不是常规的 ISO8859-1。

关于没有 RessourceBundle 的 Java i18n,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13418858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com