Как взаимодействовать с содержимым ZipFile в алфавитном порядке?

#java #zip

#java #zip

Вопрос:

У меня большой .zip архив с тысячами файлов. Как я могу выполнить их итерацию в определенном порядке (например, по возрастанию в алфавитном порядке)?

 try (ZipFile zip = new ZipFile(archive)) {
    Enumeration<? extends ZipEntry> entries = zip.entries();
    while (entries.hasMoreElements()) {
        var file = entries.nextElement();
        //...
    }
}
  

Я обнаружил, что потоковая передача может быть вариантом. Но возможно ли это и без потоковой передачи?

 List<? extends ZipEntry> list = zip.stream()
        .sorted(Comparator.comparing(ZipEntry::getName))
        .collect(Collectors.toList());
  

Комментарии:

1. Вы пробовали использовать zip.stream() и сортировать поток в соответствии с желаемым порядком?

2. Да, смотрите мою правку. Но я бы предпочел сортировку без необходимости явно запускать поток.

3. Разве вы не можете просто перечислить перечисление и отсортировать его таким образом? kodejava.org/how-do-i-sort-an-enumeration

4. Я имею в виду, вы всегда можете отсортировать свое перечисление, преобразовав его в список и отсортировав с помощью Collections.sort . Но на самом деле это не лучше, чем потоковое imo.

5. Вы можете получить все записи и использовать Collections.sort() или любой другой из множества способов сортировки объектов в Java. Нет понятия «сортировка zip», поэтому ваш вопрос сводится к «как мне сортировать объекты».

Ответ №1:

Не существует определенного для ZipFile способа сортировки записей ZipFile или «чтения» упорядоченного содержимого ZipFile. Единственная ссылка на упорядочение в ZipFile Javadoc — при использовании ZipFile.stream .

В этом случае записи «[…] отображаются в потоке в том порядке, в котором они отображаются в центральном каталоге ZIP-файла».

Итак, вы остаетесь с обычными подходами при упорядочении / сортировке в java:

Либо используйте метод stream() для извлечения потока, упорядочите его и выполните свою логику:

 zip.stream()
   .sorted( Comparator.comparing( ZipEntry::getName ) ) // define your order
   .forEach( this::doStuff ); // do your logic, in this example it is a method in this class
  

или преобразовать перечисление в коллекцию и отсортировать коллекцию, например, как

 List< ? extends ZipEntry > entries = Collections.list( zip.entries() );
entries.sort( Comparator.comparing( ZipEntry::getName ) ); // define your order
for (ZipEntry entry : entries) {
    doStuff(entry);
}