我正在阅读一些包含字符串的.csv文件,该字符串显示十进制数字。我的麻烦是很多次我用不同的语言环境来重写文件写入。例如:
现在我试图以这种方式读取值:
DecimalFormatSymbols dfs = new DecimalFormatSymbols(new Locale(en,US));
DecimalFormat df= new DecimalFormat();
df.setDecimalFormatSymbols(dfs);
df.setParseBigDecimal(true);
bigDecimal = (BigDecimal) df.parse(value);
使用此代码段,第一个值变为12913(不正确),而第二个变为129.13(正确)。现在我希望如果我使用en_US local并且文件包含使用的值,比如小数分隔符,我必须抛出异常。
我该怎么做?
答案 0 :(得分:0)
虽然在使用char
时无法为组分隔符设置任何内容(null)(因为它是DecimalFormatSymbols
),但您可以将其设置为在有效数字中找到的非常不寻常的内容,例如' @'。
DecimalFormatSymbols dfs = new DecimalFormatSymbols(new Locale(en,US));
dfs.setGroupingSeparator('@');
DecimalFormat df= new DecimalFormat();
df.setDecimalFormatSymbols(dfs);
df.setParseBigDecimal(true);
bigDecimal = (BigDecimal) df.parse(value);
答案 1 :(得分:0)
DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(currentLocale);
unusualSymbols.setDecimalSeparator('|');
unusualSymbols.setGroupingSeparator('^');
String strange = "#,##0.###";
DecimalFormat weirdFormatter = new DecimalFormat(strange, unusualSymbols);
weirdFormatter.setGroupingSize(4);
您需要设置DeciamlFormat模式以将其全部拉出来。
DecimalFormatSymbols dfs = new DecimalFormatSymbols(new Locale(en,US));
dfs.setGroupingSeparator('@');
DecimalFormat df= new DecimalFormat(#,###.#", dfs);
df.setParseBigDecimal(true);
bigDecimal = (BigDecimal) df.parse(value);
答案 2 :(得分:0)
您可以使用univocity-parsers来阅读您的CSV。
我们仍在使用版本2.0,它引入了格式自动检测,但您已经可以获得快照版本并使用它来处理这个问题。
简单示例:
public static void main(String... args) {
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.detectFormatAutomatically();
List<String[]> rows = new CsvParser(parserSettings).parseAll(new StringReader("Amount,Tax,Total\n1.99,10.0,2.189\n5,20.0,6"));
for (Object[] row : rows) {
System.out.println(Arrays.toString(row));
}
System.out.println("####");
rows = new CsvParser(parserSettings).parseAll(new StringReader("Amount;Tax;Total\n1,99;10,0;2,189\n5;20,0;6"));
for (Object[] row : rows) {
System.out.println(Arrays.toString(row));
}
}
输出:
[Amount, Tax, Total]
[1.99, 10.0, 2.189]
[5, 20.0, 6]
####
[Amount, Tax, Total]
[1,99, 10,0, 2,189]
[5, 20,0, 6]
您可以从here获取最新的快照版本。
或者,如果您使用maven,请将其添加到 pom.xml :
<repositories>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
并将版本设置为2.0.0-SNAPSHOT:
<dependency>
<groupId>com.univocity</groupId>
<artifactId>univocity-parsers</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
如果您发现任何问题,只需打开一个新问题in the project's github page
编辑:使用多个格式化程序演示如何将输入行转换为BigDecimal的另一个示例:
public static void main(String... args) {
// ObjectRowListProcessor converts the parsed values and stores the result in a list.
ObjectRowListProcessor rowProcessor = new ObjectRowListProcessor();
FormattedBigDecimalConversion conversion = new FormattedBigDecimalConversion();
conversion.addFormat("0.00", "decimalSeparator=.");
conversion.addFormat("0,00", "decimalSeparator=,");
// Here we convert fields at columns 0, 1 and 2 to BigDecimal, using two possible input formats
rowProcessor.convertIndexes(conversion).set(0, 1, 2);
// Create a settings object to configure the CSV parser
CsvParserSettings parserSettings = new CsvParserSettings();
//I'll separate the values using | to make it easier for you to identify the values in the input
parserSettings.getFormat().setDelimiter('|');
// We want to use the RowProcessor configured above to parse our data
parserSettings.setRowProcessor(rowProcessor);
// Create the parser
CsvParser parser = new CsvParser(parserSettings);
// Parse everything. All rows are sent to the rowProcessor configured above
parser.parse(new StringReader("1.99|10.0|2.189\n1,99|10,0|2,189"));
// Let's get the parsed rows
List<Object[]> rows = rowProcessor.getRows();
for (Object[] row : rows) {
System.out.println(Arrays.toString(row));
}
}
这里有输出:2个带有BigDecimal对象的数组,以及正确的值:
[1.99, 10.0, 2.189]
[1.99, 10.0, 2.189]