【问题标题】:Adding column to CSV file with StringBuffer values (Java)使用 StringBuffer 值将列添加到 CSV 文件(Java)
【发布时间】:2014-04-27 20:39:25
【问题描述】:

假设我有一个值为 "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 循环之外声明所有变量)。到目前为止,此代码有效。问题是这些列不是并排的,这就是我想要的。我知道我可能需要创建临时文件,但我需要非常小心地处理这个问题,因为我将来可能需要有很多列。

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 为什么要使用 StringBuffer?
  • @Braj 我什么都没试过。我目前的程序将所有内容存储为列,考虑到 Excel 最多只支持 16,000 列,这并不好。
  • String 上的\n 输入拆分为List&lt;String&gt;。遍历文件中的行并将每个List 元素附加到每行的末尾。写入新文件。
  • @n1234 我使用 StringBuffer 因为它是线程安全的。

标签: java csv stringbuffer


【解决方案1】:

显然有两个基本要求:

  1. 将列附加到现有的CSV 文件
  2. 允许并发操作

为了实现要求#1,必须将原始文件读取并重写为新文件,包括新列,无论其位置如何(即在StringBuffer 或其他地方) .

读取CSV 文件的最佳(也是唯一通用)方法是通过成熟且经过现场验证的库,例如OpenCSV,鉴于其Apache 2.0 license,它是轻量级且商业友好的。否则,必须进行许多简化(例如,始终假定单行 CSV 记录),或者通过实现新的 CSV 解析器重新发明轮子。

无论哪种情况,都需要一个简单的算法,例如:

  • 从使用的库(或使用的任何自定义解决方案)初始化 CSV 读取器或解析器对象,提供现有的 CSV 文件和必要的参数(例如,字段分隔符)。
  • 通过阅读器或解析器以String[]List&lt;String&gt; 结构逐记录读取输入文件。
  • 处理为每条记录返回的结构,以添加或删除内存中的任何额外字段(列)。
  • 如果需要或需要,添加空白字段(即,仅额外的分隔符,每个字段 1 个)。
  • 使用库中的 CSV 写入器(或手动实现写入器)将新记录写入输出文件。
  • 在写入输出文件的每条记录的末尾附加一个换行符。
  • 对原始CSV 文件中的所有记录重复。

这种方法也是可扩展的,因为它不需要任何重要的内存处理。

对于要求 #2,支持并发的方法有很多,在这种情况下,以量身定制的方式(即,在应用程序中“手动”)更有效,而不是依赖于像StringBuffer这样的线程安全数据结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 2020-07-18
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    相关资源
    最近更新 更多