在Java中,我如何找到我的Resource Bundle可用的语言

Pau*_*lor 20 java resourcebundle internationalization

我在主jar中打包了一些资源包

widget_en.properties
widget_de.properties
Run Code Online (Sandbox Code Playgroud)

我根据我的默认语言环境检索资源包作为folows

ResourceBundle.getBundle("widget", Locale.getDefault());
Run Code Online (Sandbox Code Playgroud)

但我想向用户提供支持的可用语言列表,以便选择可能与其计算机默认的语言不同的语言

但我在ResourceBundle中找不到列出可用语言环境的方法,我不想硬编码列表,因为我可能忘记在添加另一个资源包时更新它.

编辑

因为我只为不同的语言资源包(我没有国家改进)所以我通过迭代所有已知的语言代码并检查每一个作为资源来生成列表.

String[]langs = Locale.getISOLanguages();
for(String lang:langs)
{
      URL rb = ClassLoader.getSystemResource("widget_"+lang+".properties");
      if(rb!=null)
      {
            System.out.println("Found:"+rb.toString());
      }
}
Run Code Online (Sandbox Code Playgroud)

dce*_*chi 5

我认为没有用于此目的的 API,因为可以动态创建新的有效区域设置对象:

Locale locale = new Locale("abcd");
Run Code Online (Sandbox Code Playgroud)

无需在某处注册。然后你就可以 widget_abcd.properties不受限制地使用资源包:

ResourceBundle resource= ResourceBundle.getBundle("widget", new Locale("abcd"));
Run Code Online (Sandbox Code Playgroud)

来自java.util.LocaleAPI 文档:

由于 Locale 对象只是区域的标识符,因此在构造 Locale 时不会执行有效性检查。如果您想查看特定资源是否可用于您构建的区域设置,则必须查询这些资源。

要解决该问题,您仍然可以迭代资源目录中名为“widget_”的所有文件并发现新添加的资源包。

请注意,由于上述原因,这Locale.getAvailableLocales() 并不是 100% 确定:您可能有一天会定义一个非标准区域设置。但是,如果您只添加一些标准区域设置,则可以使用此静态方法来迭代系统区域设置并获取相应的包。


Koh*_*ert 5

如果你真的打包资源文件里面你的JAR,那么我会做这样的:

public static void main(String[] args) {
  Set<ResourceBundle> resourceBundles = getResourceBundles(A.class.getName());
  if (resourceBundles.isEmpty())
    // ...
}

public static Set<ResourceBundle> getResourceBundles(String baseName) {
  Set<ResourceBundle> resourceBundles = new HashSet<>();

  for (Locale locale : Locale.getAvailableLocales()) {
    try {
      resourceBundles.add(ResourceBundle.getBundle(baseName, locale));
    } catch (MissingResourceException ex) {
      // ...
    }
  }

  return Collections.unmodifiableSet(resourceBundles);
}
Run Code Online (Sandbox Code Playgroud)

如果你关心你的JAR,那么你至少会得到一个包含给定的默认资源的集合baseName.

如果您只有具有名称的资源,则baseName_<country>此方法可以完美地运行,因为只有那些ResourceBundles将添加到您的JAR中存在的集合中.它会工作,即使你决定你需要独立baseName_en_USbaseName_en_UK资源,这并非闻所未闻.

无耻的自我插件:我写了ResourceBundle.Control一个Charset以其参数为例,如果你想加载UTF-8编码的资源文件,你可能会感兴趣.它可以在GitHub上找到.