在Java中,我如何找到哪些语言可以使用我的资源包

我有一些资源包打包在我的主jar中

widget_en.properties
widget_de.properties

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

ResourceBundle.getBundle("widget", Locale.getDefault());

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

但是我在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());
      }
}

答案 1

如果你真的把资源文件打包在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);
}

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

如果您只有具有类似此方法的名称的资源,则可以完美地工作,因为只有这些资源才会添加到 JAR 中存在的集合中。即使您决定需要单独的资源,它也会起作用,这并非闻所未闻。baseName_<country>ResourceBundlesbaseName_en_USbaseName_en_UK

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


答案 2

我不认为有一个API可以做到这一点,因为可以动态创建新的有效区域设置对象:

Locale locale = new Locale("abcd");

无需在某个地方注册。然后,您可以不受限制地使用资源包:widget_abcd.properties

ResourceBundle resource= ResourceBundle.getBundle("widget", new Locale("abcd"));

来自 API 文档:java.util.Locale

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

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

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


推荐