Как создать плоский архив на молнии
Ваш zip Archive может иметь в нем другие архивы Zip. Можно захотеть извлечь вложенное содержимое архива Zip в родительский архив, чтобы получить плоскую структуру.
современная архивная структура
outer.zip ├first.txt ├inner.zip │ ├game.exe │ └subitem.bin └picture.gif
Желаемая архивная структура
flatten.zip ├first.txt ├picture.gif ├game.exe └subitem.bin
Если вы не знакомы с Aspose.zip, прочитайте, как извлечь Zip Archive Сначала.
Переверное объяснение
Во -первых, нам нужно перечислить все записи архива. Регулярные записи должны храниться такими, какие они есть, мы не должны даже распаковать их. Записи, которые сами являются архивами, должны быть извлечены в память и удалены из внешнего архива. Их содержание должно быть включено в основной архив.
Обнаружение записей, которые являются архивами
Давайте решим, какие записи сами по себе. Мы можем выяснить это по расширению имени входа. Позже мы удалим эти записи из главного архива, поэтому храните такие записи в списке.
1if (entry.getName (). tolowercase (locale.root) .endswith (". Zip")) {
2 EntriestoDelete.Add (entry);
3 ...
4}
Извлечение контента ввода в память
Aspose.zip позволяет извлекать содержание входа ZIP в любой riseable -поток не только в файл. Итак, мы можем извлечь вложенный архив в поток памяти.
Обратите внимание: виртуальная память должна быть достаточно большой, чтобы сохранить весь извлеченный контент.
1байт [] b = новый байт [8192];
2int bytesread;
3InputStream intryStream = intrint.open ();
4BytearRayOutputStream InnerCompressed = New BytearRayOutputStream ();
5while (0 <(bytesread = intrintstream.read (b, 0, b.length))) {
6 InnerCompressed.Write (B, 0, BytesRead);
7}
После этого внутренний поток содержит сам внутренний архив. Архив -конструктор позволяет декомпрессировать предоставленный поток. Итак, мы можем также извлечь это:
1Archive Inner = новый архив (новый BytearrayinputStream (InnerCompressed.TobyTearray ()));
исключая записи
Мы можем удалить запись из Zip Archive с конкретным методом.
1для (ArchiveEntry E: EntriestoDelete) {
2 Внешний.deleteEntry (e);
3}
Сделайте все это вместе
Вот полный алгоритм.
1Попробуйте (Archive Outter = New Archive ("over.zip")) {
2 ArrayList <ArchiveEntry> intriestoDelete = new ArrayList <ArchiveEntry> ();
3 Arraylist <string> namestoinsert = new ArrayList <string> ();
4 ArrayList <InputStream> contentToinSert = new ArrayList <InputStream> ();
5 для (ArchiveEntry запись: over.getEntries ()) {
6 // Найти запись, которая является самой архивом
7 if (entry.getName (). tolowercase (locale.root) .endswith (". Zip")) {
8 // сохраняйте ссылку на запись, чтобы удалить его из архива позже
9 EntriestoDelete.Add (entry);
10
11 //This extracts the entry to a memory stream
12 byte[] b = new byte[8192];
13 int bytesRead;
14 InputStream entryStream = entry.open();
15 ByteArrayOutputStream innerCompressed = new ByteArrayOutputStream();
16 while (0 < (bytesRead = entryStream.read(b, 0, b.length))) {
17 innerCompressed.write(b, 0, bytesRead);
18 }
19
20 // We know that content of the entry is a zip archive, so we may extract
21 try(Archive inner = new Archive(new ByteArrayInputStream(innerCompressed.toByteArray()))) {
22
23 // Loop over entries of inner archive
24 for(ArchiveEntry ie : inner.getEntries()) {
25
26 // Keep the name of inner entry.
27 namesToInsert.add(ie.getName());
28
29 InputStream ieStream = ie.open();
30 ByteArrayOutputStream content = new ByteArrayOutputStream();
31 while (0 < (bytesRead = ieStream.read(b, 0, b.length))) {
32 content.write(b, 0, bytesRead);
33 }
34
35 // Keep the content of inner entry.
36 contentToInsert.add(new ByteArrayInputStream(content.toByteArray()));
37 }
38 }
39 }
40 }
41
42 for(ArchiveEntry e : entriesToDelete) {
43 // Delete all the entries which are archives itself
44 outer.deleteEntry(e);
45 }
46
47 for(int i = 0; i < namesToInsert.size(); i++) {
48 // Adds entries which were entries of inner archives
49 outer.createEntry(namesToInsert.get(i), contentToInsert.get(i));
50 }
51
52 outer.save("flatten.zip");
53} catch (Exception ex) {
54 System.out.println (Ex);
55}