我创建了一个Web应用程序模块,用于将CSV文件导入DB。在导入过程之后,用户将显示摘要,例如输入文件中的记录总数,导入到db的良好记录总数以及拒绝记录的总数。用户可以下载成功和错误记录以进行验证。
问题是一些重复记录会附加到成功和错误文件中。例如,用户收到如下消息:
总记录数:2099
好记录数:1694
跳过的记录数:405
点击下载成功文件:Import_20121012184828_success.csv
单击以下载错误文件:Import_20121012184828_errors.csv
当我们检查数据库时,表中的记录数正好是“1694”(与预期的良好记录数相同)。但在Import_20121012184828_success.csv文件中有“1741”记录。但是在eclipse控制台中,它与db中的打印相同,即在上一次成功记录之后没有重复。所以一旦退出循环,当我调用successCsvMapWriter.close();和errorCsvMapWriter.close();一些来自缓冲区的记录正在加起来。我无法弄清楚这一点。
注意:对于少量输入,我根本没有注意到任何问题。尝试使用版本1.52和2.0.0 beta。
以下是创建结果文件的代码:
File successFile = new File(csvFileDetails.getSuccessFileUrl());
File errorFile = new File(csvFileDetails.getErrorFileUrl());
// Create result files.
successFile.createNewFile();
errorFile.createNewFile();
String[] header = csvFileDetails.getHeader();
String[] errorFileHeader = ArrayUtils.add(header,
CatalogImportConstanst.CSV_ERROR_HEADER);
// Also tried CsvPreference.STANDARD_PREFERENCE
ICsvMapWriter successCsvMapWriter = new CsvMapWriter(new BufferedWriter(
new FileWriter(successFile)), CsvPreference.EXCEL_PREFERENCE);
ICsvMapWriter errorCsvMapWriter = new CsvMapWriter(new BufferedWriter(
new FileWriter(errorFile)), CsvPreference.EXCEL_PREFERENCE);
successCsvMapWriter.writeHeader(header);
successCsvMapWriter.flush();
errorCsvMapWriter.writeHeader(errorFileHeader);
errorCsvMapWriter.flush();
int errorCount = 0;
int successCount = 0;
for (Map<String, String> csvRecord : csvAsList) {
if (csvRecord.get(CatalogImportConstanst.CSV_ERROR_HEADER) != null
&& csvRecord.get(CatalogImportConstanst.CSV_ERROR_HEADER).trim().length() > 0) {
errorCsvMapWriter.write(csvRecord, errorFileHeader);
errorCsvMapWriter.flush();
errorCount++;
System.out.println("Error record: "+ csvRecord);
} else {
successCsvMapWriter.write(csvRecord, header);
successCsvMapWriter.flush();
successCount++;
System.out.println("Success record: "+ csvRecord);
}
}
successCsvMapWriter.close();
errorCsvMapWriter.close();
提前致谢。
答案 0 :(得分:2)
只是澄清一下,当你说你的成功文件有1741条记录时,你是在计算CSV记录还是文件中的行数?可能是你有包含嵌入换行符的记录,这意味着你不能简单地计算行数(即这实际上是重复还是你计算不正确?)。
您可以使用getRowNumber()
来返回写入的行数(包括标题),而不是自己维护记录计数。如果你在方法结束时调用它,它会返回什么?
successCsvMapWriter.close();
errorCsvMapWriter.close();
System.out.println("Success records (including header): " +
successCsvMapWriter.getRowNumber());
System.out.println("Error records (including header): " +
errorCsvMapWriter.getRowNumber());
哦,你不需要所有这些flush()
语句 - 当你拨打close()
时,会刷新流。