如何从Java中的OS读取“列表分隔符”?

我正在编写一个Java导出器,它应该尊重用户的自定义设置,尤其是用作分隔符的“列表分隔符”。

在Windows中,可以设置此List分隔符

Control Panel -> Regional and Language Options -> Regional Options -> Customize 

我不知道其他操作系统,但我很确定你也可以在其他操作系统上改变它。

将此自定义设置从操作系统转换为Java的最佳方法是什么? 我在Eclipse RCP环境中,所以如果有可用的话,我可能会使用与RCP相关的解决方案。

从这个答案的评论:

读取特定于操作系统的设置是我必须要满足的。

那么,如果Windows以外的操作系统没有这样的设置呢?

我建议你从Windows上的注册表中读取它(如此处所提到的): 使用Java读取/写入Windows注册表 。 在其他平台上只使用一个很好的默认值,也许,至少在Unix上,也支持通过自定义环境变量(你很好地记录)配置它: 我的java代码如何读取OS环境变量? 。

我的直觉是操作系统普遍没有(系统范围或用户特定的)“列表分隔符”设置可能是错误的,当然,但我怀疑。

如果不采用特定于平台的解决方案,我认为最好的方法是允许用户在自己的应用程序中指定列表分隔符的首选项。 在首选项面板中,导出时的对话框或通过可选的命令行参数。

除了在应用程序中为用户提供自己的选项之外,您还可以尝试猜测列表分隔符是什么。

我看了一下Windows中的一些语言环境,看到列表分隔符是“;” 要么 ”,”。 我听说在一些不起眼的地方还有另一个角色,但我自己也没看过。 因此,如果您可以使您的代码同时处理“;” 和“,”作为列表分隔符,那么你可能会涵盖大多数情况。

此外,看起来当“,”用作小数分隔符时,“,”从不用作列表分隔符。 我猜这是否则数字将无法在列表中区分:1,2,3,4可能是1.2,3.4或1,2.3在这些情况下“;” 用作列表分隔符。 不幸的是,事实并非如此。 阿拉伯语有“。” 作为小数符号和“;” 作为列表分隔符。

所以我认为可以合理安全地遵循的规则是:

 if (decimalSeparator == ',') then listSeparator = ';' else if (decimalSeparator == '.') then listSeparator = new char[] {';', ','} 

出于好奇,我搜索了一些主题,事实上Java似乎没有开箱即用的概念。

Locales Demo提供了相当完整的区域设置列表,并且没有列表分隔符。

我看到一个引用sun.text.resources包的论坛问题 ,该问题是私有的并且已弃用。 您将找不到对此程序包的其他引用,看起来它位于jre / lib / ext / localedata.jar中,尽管我最近的副本列出了大部分亚洲语言环境。

以上建议是合理的,或者您可以研究并使用每个区域设置的私有列表。 我想看看IBM的ICU库(我认为的C语言),它似乎有一个相当大的语言环境设置列表。 根据评论 ,ICU本身从ISO标准获取其信息,该标准应作为主要信息提供者进行研究。

我遇到了同样的问题,并且发现唯一合适的解决方案是为用户提供一种指定“选择分隔符”的方法。

但是,如果这不可能,就像我的情况那样,最接近我可以跨越平台,跨区域支持如下:

  • 使用DecimalFormatSymbols猜测你需要使用的分隔符
  • 在包含CSV的开头添加一行,例如“sep =”(不带引号),这应该指定您刚刚猜到的列表分隔符

至少在大多数情况下(我已经测试过的情况),这将迫使Excel使用该分隔符,即使您“猜错了”并且将提供至少更多的兼容性。

对于Windows,它存储在注册表中:

 "HKEY_CURRENT_USER\\Control Panel\\International" 

所以你可以使用这样的东西

 private void setDelimiterProperties(String delimiter) { Properties p = new Properties(); String key = "HKEY_CURRENT_USER\\Control Panel\\International\\sList"; p.setProperty(key, delimiter); }