Сравнение файлов - содержимое может быть неупорядоченным

1

Файлы под папкой1 и папкой2 будут иметь одинаковые имена, и я хочу, чтобы 2 сравнивал эти файлы. Меня поразило это. Есть ли какой-либо JAVA API для этого сравнения. Размеры файлов могут быть огромными

Пример:

folder1/file1
----------
kushi,metha,2
kushi,barun,1
arun,mital,3

folder2/file1
----------
arun,mital,3
kushi,metha,2
sheetal,kumar,3
kushi,barun,1

Сравнение файлов file1 и file2 должно возвращать "листовой кумар 3". Я пробовал поиск в Google, но не смог найти ничего полезного.

Теги:

3 ответа

2

Я знаю, что это не чисто Java-решение, но если у вас есть доступ к окну * nix:

sort file1 > sorted1; sort file2 > sorted2;comm -3 sorted1 sorted2;

Дала бы вам именно то, что вам нужно.

И затем взгляните на этот вопрос о том, как вы можете запускать скрипты оболочки из java.

РЕДАКТИРОВАТЬ:

Я пытаюсь сказать, что для вычисления diff существует 2 шага:

  1. Отсортируйте файлы.
  2. Сравните их по строкам, чтобы найти различия.
  • 0
    Спасибо .. Но как я узнаю, в каком файле строки различаются?
  • 0
    Если вам это интересно, могу я предложить diff . Опять же, все это стандартные утилиты оболочки Unix.
0

Я столкнулся с той же проблемой и напишу функцию сравнения:

/**
 * Compare two sequences of lines without considering order.
 * <p>
 * Input parameter will not be modified.
 */
public static <T> boolean isEqualWithoutOrder(final T[] lines1, final T[] lines2) {
    if (lines1 == null && lines2 == null) return true;
    if (lines1 == null) return false;
    if (lines2 == null) return false;
    if (lines1.length != lines2.length) return false;

    final int length = lines1.length;
    int equalCnt = 0;

    final boolean[] mask = new boolean[length];
    Arrays.fill(mask, true);

    for (int i = 0; i < lines2.length; i++) {
        final T line2 = lines2[i];
        for (int j = 0; j < lines1.length; j++) {
            final T line1 = lines1[j];
            if (mask[j] && Objects.equal(line1, line2)) {
                equalCnt++;
                mask[j] = false;

                //if two equal lines is found, more subsequent equal lines are speculated
                while (j + 1 < length && i + 1 < length &&
                        Objects.equal(lines1[j + 1], lines2[i + 1])) {
                    equalCnt++;
                    mask[j + 1] = false;
                    j++;
                    i++;
                }

                break;
            }
        }
        if (equalCnt < i) return false;
    }
    return equalCnt == length;
}

Общие коллекции могут быть медленными, сравнение скорости:

//lines1: Seq[String], lines2: Seq[String] of 100k lines of equal Random String but without ordering.
FastUtils.isEqualWithoutOrder(lines1.toArray, lines2.toArray) //97 ms
lines1.sorted == lines2.sorted //836 ms

Время, измеренное в горячей среде sbt.

(Отказ от ответственности: я только сделал базовый тест против этой функции)

0

В зависимости от того, что вы имеете в виду под огромным, вы можете использовать HashSet для первого прохождения через один файл и добавления каждой строки в хеш-набор, затем пройти через другой файл и из набора хэшей, удалить строки, которые вы сейчас читаете из другой файл. Это предполагает, что каждая строка уникальна.

  • 0
    Я думал об этом. Но есть ли 3-й сторонний / Java API для этого?
  • 1
    @kushi: Кажется, здесь что-то есть, проблема в том, что я не уверен, что он игнорирует порядок.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню