假设我有一个值为“1\n 2\n 3\n...etc”的 StringBuffer,其中\n 是一个换行符。 如何使用 Java 将这些值作为列添加到现有 CSV 文件中?具体来说,这将是最后一列。
例如,假设我有一个如下所示的 CSV 文件:
5, 2, 5
2, 3, 1
3, 5, 2
..
etc.
在使用方法将列添加到 csv 文件后,给定 StringBuffer 的输出应该如下所示:
5, 2, 5, 1
2, 3, 1, 2
3, 5, 2, 3
..
etc.
我还计划添加具有 1000 多个值的列,因此我正在寻找内存消耗不高的东西。
提前致谢。
编辑:列的大小可能不同。我看到有人说要在每一行的末尾添加它。问题是,它会将值添加到错误的列中,我不能让这种情况发生。谢谢大家的建议,因为它们非常好。
编辑 2:我收到了关于我使用 StringBuffer 的批评,是的,我同意,如果这个问题是孤立的,我也会建议使用 StringBuilder。这个问题的上下文是一个程序,它具有同步线程(作为场景)在给定一系列并发线程的情况下收集响应时间。并发线程对数据库执行并发查询,一旦执行了查询,结果就会附加到 StringBuffer 中。每个同步线程的所有响应时间都附加到 StringBuffer 并写入 CSV 文档。可以有多个线程具有相同的响应时间。我可以使用 StringBuilder,但随后我将不得不手动同步附加响应时间的线程,在我的情况下,我认为这不会对性能产生太大影响,并且会添加不必要的代码量。希望对大家有所帮助,再次感谢大家的关心和建议。如果在阅读本文后,您仍然不相信我应该使用 StringBuffer,那么我请求我们将此讨论离线。
编辑 3:如果行的大小不同,我已经想出如何解决添加列的问题。我只是为每个缺失的列添加逗号(另请注意,我的行会随着每一列而增长)。看起来@BorisTheSpider 的概念解决方案实际上适用于此修改。问题是我不确定如何在每一行的末尾添加文本。到目前为止我的代码(我删除了代码以节省空间):
//Before this code there is a statement to create a test.csv file (this file has no values before this loop occurs).
for (int p = 0; p<(max+1); p = p + inc){
threadThis2(p);
//threadThis2 appends to the StringBuffer with several comma delimited values.
//p represents the number of threads/queries to execute at the same time.
comma = p/inc; //how many commas to put if there is nothing on the line.
for (int i = 0; i < comma; i++) {
commas.append(",");
}
br = new BufferedReader (new FileReader("test.csv"));
List <String> avg = Arrays.asList(sb.toString().split(", "));
for (int i = 0; i < avg.size(); i++) {
if (br.readLine()==null)
{w.write(commas.toString() + avg.get(i).toString() + ", \n");}
else { w.write(avg.get(i).toString() + ", \n");}
}
br.close();
sb.setLength(0);
commas.setLength(0);
}
请注意这段代码处于早期阶段(我当然会稍后在 for 循环之外声明所有变量)。到目前为止这段代码有效。问题是列不是并排的,这正是我想要的。我知道我可能需要创建临时文件,但我需要非常小心地处理这个问题,因为将来我可能需要有很多列。
最佳答案
显然有两个基本要求:
- 向现有的
CSV
添加一列文件 - 允许并发操作
要实现要求 #1,必须读取原始文件并将其重写为新文件,包括新列,无论其位置如何(即,在 StringBuffer
或其他地方) .
阅读 CSV
的最佳(也是唯一通用)方式文件将通过成熟且经过现场验证的库,例如 OpenCSV ,这是轻量级和商业友好的,鉴于其 Apache 2.0 license
.否则,必须要么做很多简化(例如,总是假设单行 CSV
记录),要么通过实现新的 CSV
来重新发明轮子。解析器。
无论哪种情况,都需要一个简单的算法,例如:
- 初始化
CSV
来自使用的库(或来自使用的任何自定义解决方案)的读取器或解析器对象,提供现有的CSV
文件和必要的参数(例如,字段分隔符)。 - 通过阅读器或解析器逐条记录地读取输入文件,作为
String[]
或List<String>
结构。 - 操纵为每条记录返回的结构,以添加或删除内存中的任何额外字段(列)。
- 如果需要或需要,添加空白字段(即只是额外的分隔符,每个字段 1 个)。
- 使用
CSV
库中的编写器(或手动实现编写器)将新记录写入输出文件。 - 在写入输出文件的每条记录的末尾附加一个换行符。
- 对原始
CSV
中的所有记录重复文件。
这种方法也是可扩展的,因为它不需要任何重要的内存处理。
对于要求 #2,有很多方法可以支持并发,在这种情况下,以量身定制的方式(即在应用程序中“手动”执行)更有效,而不是依赖线程安全的数据结构,如 StringBuffer
.
关于java - 使用 StringBuffer 值将列添加到 CSV 文件 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23328719/