首先,我是Java的新手,我需要一些帮助解决以下问题。
我有一个包含数百万条记录的Java列表。我想将此数据列表导出为CSV文件。以下是我编写的用于读取数据的函数,但是数百万条记录失败了。你能建议任何更好的方法吗?
private String generateCsvData(List<Map<String, Object>> rows) {
String output = reportService.getReportHeadder();
for (Map row : rows) {
output += (Long) row.get("branchId")
+ ","
+ StringEscapeUtils.escapeCsv((String) row.get("branches"))
+ ","
+ StringEscapeUtils.escapeCsv((String) row
.get("categoryName"))
+ ","
+ StringEscapeUtils.escapeCsv((String) row.get("products"))
+ ","
+ StringEscapeUtils.escapeCsv((String) row.get("emails"))
+ ","
+ StringEscapeUtils.escapeCsv((String) row
.get("contactAddress"))
+ ","
+ StringEscapeUtils.escapeCsv((String) row
.get("contactDet")) + ","
+ StringEscapeUtils.escapeCsv((String) row.get("url"))
+ "\n";
}
return output;
}
答案 0 :(得分:3)
我建议使用OpenCSV。它对reading and writing data to CSV files有非常好的支持。
答案 1 :(得分:3)
是的,轻松愉快。
如果您想立即将所有记录保存在内存中,则表示您遇到了问题。您的计算机只有很多内存,只有一部分内存分配给JVM。当你填补它时,游戏就结束了。您已拥有Map
中的数据。当您必须同时存储其.csv表示时,您可以将问题翻倍。
一种解决方案是一次流出一行。您可以遍历Map
并仅存储数据一次。
另一种解决方案可能是将所有数据存储在关系数据库表中。您可以迭代ResultSet
并以这种方式流式传输结果。现在你真的减少了你的记忆需求。
您创建行的机制并不好。我更喜欢StringBuilder
过度连接。
答案 2 :(得分:2)
问题是你正在创建一个veeeery long字符串,然后想把它写入文件。
此外,你正在连接每个tiem创建一个新的String。在这些情况下,请使用StringBuilder
您必须使用流顺序写入。 basic io开始学习的好点
答案 3 :(得分:1)
在写入文件之前将所有内容存储在字符串中,如果在生成文件时逐行写入该文件会怎样?
答案 4 :(得分:1)
使用OpenCSV等CSV库。
您可以逐行处理文件 - 读取一行,然后处理它,然后再次丢弃它。这样,文件中最多只有一行在内存中。
答案 5 :(得分:1)
首先,如果你在一个循环中构造一个字符串,不要连接字符串,但我们要StringBuilder
,因为它通常表现得更好,并且不会用很多中间字符串来摧毁你的内存。
但是在这种情况下,我建议不要将所有内容保存在内存中,而是在处理过程中直接写入文件。这将减少所需的内存。查看PrintWriter
或查找已经满足您需求的库(例如OpenCSV)。
答案 6 :(得分:0)
为什么不使用像Spring Batch这样的框架,它的块操作有助于理论上编写很多!!!!!!!记录