【问题标题】:Best way to compare big csv files?比较大 csv 文件的最佳方法?
【发布时间】:2014-03-24 08:56:36
【问题描述】:

我必须做一个应用程序,比较一些非常大的csv 文件,每个文件有 40,000 条记录。我已经完成了一个应用程序,它可以正常工作,但是它花费了大量时间进行比较,因为这两个文件可能是混乱的或有不同的记录 - 为此我必须迭代 (40000^2)*2 次。

这是我的代码:

  if (nomFich.equals("CAR"))
    {
    while ((linea = br3.readLine()) != null)
    {

                array =linea.split(",");
                spliteado = array[0]+array[1]+array[2]+array[8];

                FileReader fh3 = new FileReader(cadena + lista2[0]);
                BufferedReader bh3 = new BufferedReader(fh3);

                find=0;

                while (((linea2 = bh3.readLine()) != null))

                {
                    array2 =linea2.split(",");
                    spliteado2 = array2[0]+array2[1]+array2[2]+array2[8];


                    if (spliteado.equals(spliteado2))
                    {

                        find =1;
                    }

                }
                if (find==0)

                {
                    bw3.write("+++++++++++++++++++++++++++++++++++++++++++");
                    bw3.newLine();
                    bw3.write("Se han incorporado los siguientes CGI en la nueva lista");
                    bw3.newLine();
                    bw3.write(linea);
                    bw3.newLine();
                    aparece=1;
                }
                bh3.close();


    }

我认为在 Java 中使用 Set 是一个不错的选择,如下面的帖子所示: Comparing two csv files in Java

但在我尝试这种方式之前,我想知道是否有更好的选择。

谢谢大家。

【问题讨论】:

    标签: java comparator


    【解决方案1】:

    就我可以解释您的代码而言,您需要找出第一个 CSV 文件中的哪些行在第二个 CSV 文件中没有相同的行。对吗?

    如果是这样,您只需将第二个 CSV 文件的所有行放入 HashSet。像这样(Java 7 代码):

    Set<String> linesToCompare = new HashSet<>();
    try (BufferedReader reader = new BufferedReader(new FileReader(cadena + lista2[0]))) {
        String line;
        while ((line = reader.readLine()) != null) {
            String[] splitted = line.split(",");
            linesToCompare.add(splitted[0] + splitted[1] + splitted[2] + splitted[8]);
        }
    }
    

    之后,您可以简单地遍历第一个 CSV 文件中的行并进行比较:

    try (BufferedReader reader = new BufferedReader(new FileReader(...))) {
        String line;
        while ((line = reader.readLine()) != null) {
            String[] splitted = line.split(",");
            String joined = splitted[0] + splitted[1] + splitted[2] + splitted[8];
            if (!linesToCompare.contains(joined)) {
                // handle missing line here
            }
        }
    }
    

    这符合您的需求吗?

    【讨论】:

    • 我真的需要找到这两件事,每个csv中的新行,并找到具有相似id的两行中的更改,我会尝试你说的选项。但是我有一个新问题,我只能使用 jre 1.6,因为这个应用程序可以在我无法更改任何东西的服务器上运行。
    【解决方案2】:
    HashMap<String, String> file1Map = new HashMap<String, String>();
    
    while ((String line = file1.readLine()) != null) {
      array =line.split(",");
      key = array[0]+array[1]+array[2]+array[8];
      file1Map.put(key, key);
    }
    
    while ((String line = file2.readLine()) != null) {
      array =line.split(",");
      key = array[0]+array[1]+array[2]+array[8];
      if (file1Map.containsKey(key)) {
        //if file1 has same line in file2
      }
      else {
        //if file1 doesn't have line like in file2
      }
    }
    

    【讨论】:

    • “if (file1Map.containsKey(key, key))”这行必须是 if (file1Map.containsKey(key)) i supose。
    • 此解决方案不像需要那样工作,因为我比较了键的其他值。这只是搜索而不是两条记录之间的差异,只根据键搜索除此之外的行。
    • Deckard27,你能给我更多的信息你想做什么和一个小例子吗?因为我不明白你想做什么,你的钥匙是什么,等等。
    • 例如我有下一行 214-007-03512-20025,214-007-03512-20574,47,513,-92,3,1,30 我想和下一行比较214-007-03512-20025,214-007-03512-20574,47,513,-92,3,1,33 在这种情况下,记录的唯一 ID 是 214-007-03512-20025,214-007-03512- 20574,我想在一个 txt 文件中返回第二行中的 30 更改为 33
    • 伪代码,在我给定的示例中该怎么做: ... file1Map.put(uniqueRecordId, 30); ...在第二个同时: ... file1Map.get(uniqueRecordId).equalsIgnoreCase("33");
    【解决方案3】:

    假设这一切都不适合内存我会首先将文件转换为精简版本(el0、el1、el2、el8、orig-file-line-nr-for-reference-afterwards)然后排序说文件。之后,您可以同时流式传输这两个文件并随时比较记录...从等式中排序,您只需要“大约一次”比较它们。

    但我猜你也可以使用一些允许在内存中排序和存储的 List/Array 对象来做同样的事情; 40k 的唱片对我来说听起来真的不算多,当然,除非元素非常大。而且速度会快很多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多