8

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

在 Windows 中,可以在

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

我不了解其他操作系统,但我很确定您也可以在其他操作系统上更改它。

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

4

7 回答 7

6

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

于 2009-05-08T08:03:41.483 回答
6

这个答案的评论:

阅读特定于操作系统的设置是我必须满足的需求。

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

我建议您从 Windows 上的注册表中读取它(如此所述):Read/write to Windows Registry using Java。在其他平台上只使用一个好的默认值,也许,至少在 Unix 上,还支持通过自定义环境变量(您记录良好)配置它:我的 java 代码如何读取操作系统环境变量?.

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

于 2009-05-08T09:54:15.163 回答
5

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

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

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

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

if (decimalSeparator == ',') 
    then listSeparator = ';'
else if (decimalSeparator == '.') 
    then listSeparator = new char[] {';', ','}
于 2010-11-29T11:45:24.687 回答
2

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

语言环境演示提供了一个相当完整的语言环境设置列表,并且没有列表分隔符。

我看到一个论坛问题涉及 sun.text.resources 包,它是私有的且已弃用。您不会找到对该包的很多其他引用,看起来它位于 jre/lib/ext/localedata.jar 中,尽管我最近的这个副本主要列出了亚洲语言环境。

上述建议是合理的,或者您可以研究并使用每个区域设置的私人列表。我可能会看看 IBM 的 ICU 库(我认为是 C 语言),它似乎有一个相当大的语言环境设置列表。据介绍 ICU本身的信息来源于一个ISO标准,应该作为主要的信息提供者进行研究。

于 2009-05-08T10:16:13.253 回答
1

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

但是,如果这是不可能的,就像我的情况一样,我可以得到的最接近跨平台、跨语言环境的支持如下:

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

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

于 2015-12-16T15:35:07.697 回答
1

好吧,我认为这是一个严肃的话题!

问题是在 Windows 中,有 Excel。许多程序必须与之交互。Excel 使用列表分隔符区域设置(单元格分隔)。

基本问题是“逗号分隔值”在美国(西班牙语(美国))和英语之外不起作用,因为您不能使用与小数分隔符相同的列表分隔符。因此,美国和英语以外的世界(包括(应该)遵循北约语言环境、十进制逗号等和 ISO 措施的美国军队)使用;列表分隔符来分隔电子表格中的单元格,而不是将其与十进制逗号混淆。

所以一般来说,列表分隔符的区域设置 Windows 设置;除了英语或美国列表分隔符是,.

Excel 有其美国/英语 CSV 的不便之处,特别是;在默认的美国和英语设置中,相同的字符,是千位分隔符,而 Excel 会发疯(单元格在使用它的情况下导入 CSV)。跳过千位分隔符(当它与列表分隔符相同时) Excel 不识别货币单元格并将它们作为文本。我们必须在美国和英国环境中使用的东西,否则在世界范围内它可以正常工作(使用;)。

有趣的事情(有趣的想法)是 Windows 中的 Java 是否支持具有 Win32 库访问权限的 NDK?因为在 Win32 中你调用

GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SLIST, pwListSeparator, 4); 

我找不到获取列表分隔符的 Java 解决方案?

我的建议是使用硬编码的一般规则,将列表分隔符设置为;小数点分隔符,,否则将列表分隔符设置为,如果在 Win32 等语言环境方法或设置中找不到另一个字符。如果千位分隔符与列表分隔符相同,则删除(不要使用)千位分隔符。

还是使用选项卡式文本文件?唯一的不便是 Windows 默认使用 ShellExecute(0, 0, pwFileName, 0, 0, SW_SHOW); 在 .csv 文件上打开 Excel,在 .txt 文件上打开记事本。

值得注意的是Java中存在小数分隔符和千位分隔符,我猜应该使用:

import java.text.DecimalFormatSymbols;
new DecimalFormatSymbols().getDecimalSeparator();
new DecimalFormatSymbols().getGroupingSeparator();
于 2018-11-20T03:46:12.223 回答
-1

对于 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);
}
于 2009-05-08T07:38:48.127 回答