Як створити плоский Zip Archive
У вашому архіві пошти може бути всередині нього інші архіви блискавки. Можна захотіти витягнути вміст вкладеного Zip Archive в батьківський архів, щоб отримати рівну структуру.
Поточна архівна структура
outer.zip ├first.txt ├inner.zip │ ├game.exe │ └subitem.bin └picture.gif
Бажана архівна структура
flatten.zip ├first.txt ├picture.gif ├game.exe └subitem.bin
Якщо ви не знайомі з Aspopy.zip, прочитайте, як витягнути Zip Archive спочатку.
Пояснення
По -перше, нам потрібно перерахувати всі записи архіву. Регулярні записи повинні зберігатися такими, якими вони є, ми навіть не повинні їх декомпресувати. Записи, які самі є архівами, повинні бути витягнуті до пам’яті та видалені із зовнішнього архіву. Їх вміст повинен бути включений до основного архіву.
Виявлення записів, які є архівами
Давайте вирішимо, які записи самі архіви. Ми можемо розібратися в цьому шляхом розширення назви входу. Пізніше ми видалимо ці записи з основного архіву, тому зберігаємо такі записи у списку.
1if (entry.getName (). TOLOWERCASE (locale.root) .endswith (". Zip")) {
2 prestistodelete.add (запис);
3 ...
4}
Витягнута вмісту запису в пам’ять
Aspose.zip дозволяє витягувати вміст запису zip у будь -який потік, що записується, не лише до файлу. Отже, ми можемо витягнути вкладений архів до потоку пам’яті.
Зверніть увагу: Віртуальна пам’ять повинна бути достатньо великою, щоб зберегти весь витягнутий вміст.
1байт [] b = новий байт [8192];
2int bytesread;
3InputStream entnerstream = entry.open ();
4Bytearrayoutputstream innercompressed = новий bytearrayoutputstream ();
5while (0 <(bytesread = entnerstream.read (b, 0, b.length))) {
6 InnerCompressed.write (B, 0, BytesRead);
7}
Після цього потік іннеркомпресії містить сам внутрішній архів. Архівний конструктор дозволяє декомпресувати наданий потік. Отже, ми також можемо витягнути його:
1Архів внутрішнього = новий архів (новий bytearrayinputstream (Innercompressed.tobytearray ()));
виключаючи записи
Ми можемо видалити запис із zip Archive за допомогою конкретного методу.
1для (ArchiveEntry E: Prestistodelete) {
2 зовнішня.deleteEntry (e);
3}
Покладіть все це разом
Ось повний алгоритм.
1спробуйте (архів зовнішній = новий архів ("зовнішня.zip")) {
2 ArrayList <ChiveEntry> prestistodelete = новий ArrayList <ChiveEntry> ();
3 ArrayList <string> namestoinsert = новий ArrayList <string> ();
4 ArrayList <Putinstream> contentToinsert = новий ArrayList <Putinstream> ();
5 для (archiveentry запис: зовнішня.getentries ()) {
6 // знайти запис, який є самим архівом
7 if (entry.getName (). TOLOWERCASE (locale.root) .endswith (". Zip")) {
8 // Продовжуйте посилання на запис, щоб пізніше його зняти з архіву
9 prestistodelete.add (запис);
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} лов (виняток ex) {
54 System.out.println (ex);
55}