평평한 지퍼 아카이브를 만드는 방법
Zip 아카이브에는 그 안에 다른 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}
입력의 내용 추출 메모리에
ASSPER.zip을 사용하면 Zip Entry의 내용을 파일뿐만 아니라 쓰기 가능한 스트림으로 추출 할 수 있습니다. 따라서 중첩 아카이브를 메모리 스트림으로 추출 할 수 있습니다.
참고 : 가상 메모리는 추출 된 모든 콘텐츠를 유지하기에 충분히 커야합니다.
1바이트 [] B = 새로운 바이트 [8192];
2int bytesread;
3inputStream entrystream = enlic.open ();
4BytearRayoutputStream InnerCompressed = New BytearRayoutputStream ();
5while (0 <(bytesRead = entrystream.read (b, 0, b.length))) {
6 innercompressed.write (b, 0, 바이트 스레드);
7}
그 후 내부 압축 스트림에는 내부 아카이브 자체가 포함되어 있습니다. 아카이브 생성자는 제공된 스트림을 압축 해제 할 수 있습니다. 그래서 우리는 그것을 추출 할 수 있습니다.
1Archive Inner = New Archive (New BytearrayInputStream (InnerCompressed.tobytearRay ()));
항목 제외
특정 방법으로 Zip Archive에서 항목을 제거 할 수 있습니다.
1for (Archiveentry e : Entriestodelete) {
2 외부 .DeleteEntry (e);
3}
모든 것을 합치십시오
다음은 전체 알고리즘입니다.
1try (아카이브 OUTER = New Archive ( "OUTER.ZIP")) {
2 ArrayList <ArchiveEntry> EntriestOdelete = New ArrayList <CariveEntry> ();
3 ArrayList <string> namestoInsert = new ArrayList <string> ();
4 ArrayList <InputStream> ContentToInsert = New ArrayList <inputStream> ();
5 for (ArchiveEntry 항목 : OUTER.GETERTRIES ()) {
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 (예외) {
54 System.out.println (예);
55}