View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.commons.compress.archivers.zip;
19  
20  import static java.nio.charset.StandardCharsets.UTF_8;
21  import static org.apache.commons.compress.AbstractTest.getPath;
22  import static org.apache.commons.compress.archivers.zip.ZipArchiveEntryRequest.createZipArchiveEntryRequest;
23  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
24  import static org.junit.jupiter.api.Assertions.assertEquals;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.io.ByteArrayInputStream;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.io.OutputStream;
31  import java.nio.channels.SeekableByteChannel;
32  import java.nio.charset.StandardCharsets;
33  import java.nio.file.FileSystem;
34  import java.nio.file.Files;
35  import java.nio.file.Path;
36  import java.nio.file.StandardOpenOption;
37  import java.security.NoSuchAlgorithmException;
38  import java.security.SecureRandom;
39  import java.util.ArrayList;
40  import java.util.Comparator;
41  import java.util.EnumSet;
42  import java.util.List;
43  import java.util.Random;
44  import java.util.UUID;
45  import java.util.stream.Collectors;
46  import java.util.stream.Stream;
47  import java.util.zip.Deflater;
48  import java.util.zip.ZipEntry;
49  
50  import org.apache.commons.compress.AbstractTest;
51  import org.apache.commons.compress.archivers.ArchiveException;
52  import org.apache.commons.compress.archivers.ArchiveOutputStream;
53  import org.apache.commons.compress.archivers.ArchiveStreamFactory;
54  import org.apache.commons.compress.parallel.InputStreamSupplier;
55  import org.apache.commons.io.IOUtils;
56  import org.apache.commons.io.file.PathUtils;
57  import org.junit.jupiter.api.AfterEach;
58  import org.junit.jupiter.api.BeforeEach;
59  import org.junit.jupiter.api.Test;
60  
61  import com.github.marschall.memoryfilesystem.MemoryFileSystemBuilder;
62  
63  public class ZipMemoryFileSystemTest {
64  
65      static void println(final String x) {
66          // System.out.println(x);
67      }
68  
69      private Path dir;
70  
71      private InputStreamSupplier createPayloadSupplier(final ByteArrayInputStream payload) {
72          return () -> payload;
73      }
74  
75      @BeforeEach
76      public void setup() throws IOException {
77          dir = Files.createTempDirectory(UUID.randomUUID().toString());
78      }
79  
80      @AfterEach
81      public void tearDown() throws IOException {
82          try (Stream<Path> walk = Files.walk(dir)) {
83              walk.sorted(Comparator.reverseOrder()).peek(path -> println("Deleting: " + path.toAbsolutePath())).forEach(path -> {
84                  try {
85                      Files.deleteIfExists(path);
86                  } catch (final IOException ignore) {
87                  }
88              });
89          }
90      }
91  
92      @Test
93      public void testForPathsReturnCorrectClassInMemory() throws IOException {
94          final Path firstFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
95          final Path secondFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
96          final Path lastFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
97          final byte[] firstBytes = Files.readAllBytes(firstFile);
98          final byte[] secondBytes = Files.readAllBytes(secondFile);
99          final byte[] lastBytes = Files.readAllBytes(lastFile);
100         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
101             Files.write(fileSystem.getPath("split_zip_created_by_zip.z01"), firstBytes);
102             Files.write(fileSystem.getPath("split_zip_created_by_zip.z02"), secondBytes);
103             Files.write(fileSystem.getPath("split_zip_created_by_zip.zip"), lastBytes);
104             final ArrayList<Path> list = new ArrayList<>();
105             list.add(firstFile);
106             list.add(secondFile);
107 
108             try (SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forPaths(lastFile, list)) {
109                 assertTrue(channel instanceof ZipSplitReadOnlySeekableByteChannel);
110             }
111 
112             try (SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forPaths(firstFile, secondFile, lastFile)) {
113                 assertTrue(channel instanceof ZipSplitReadOnlySeekableByteChannel);
114             }
115         }
116     }
117 
118     @Test
119     public void testPositionToSomeZipSplitSegmentInMemory() throws IOException {
120         final byte[] firstBytes = AbstractTest.readAllBytes("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
121         final byte[] secondBytes = AbstractTest.readAllBytes("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
122         final byte[] lastBytes = AbstractTest.readAllBytes("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
123         final int firstFileSize = firstBytes.length;
124         final int secondFileSize = secondBytes.length;
125         final int lastFileSize = lastBytes.length;
126 
127         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
128             final Path lastMemoryPath = fileSystem.getPath("split_zip_created_by_zip.zip");
129             Files.write(fileSystem.getPath("split_zip_created_by_zip.z01"), firstBytes);
130             Files.write(fileSystem.getPath("split_zip_created_by_zip.z02"), secondBytes);
131             Files.write(lastMemoryPath, lastBytes);
132             final Random random = new Random();
133             final int randomDiskNumber = random.nextInt(3);
134             final int randomOffset = randomDiskNumber < 2 ? random.nextInt(firstFileSize) : random.nextInt(lastFileSize);
135 
136             try (ZipSplitReadOnlySeekableByteChannel channel = (ZipSplitReadOnlySeekableByteChannel) ZipSplitReadOnlySeekableByteChannel
137                     .buildFromLastSplitSegment(lastMemoryPath)) {
138                 channel.position(randomDiskNumber, randomOffset);
139                 long expectedPosition = randomOffset;
140 
141                 expectedPosition += randomDiskNumber > 0 ? firstFileSize : 0;
142                 expectedPosition += randomDiskNumber > 1 ? secondFileSize : 0;
143 
144                 assertEquals(expectedPosition, channel.position());
145             }
146         }
147 
148     }
149 
150     @Test
151     public void testScatterFileInMemory() throws IOException {
152         final byte[] B_PAYLOAD = "RBBBBBBS".getBytes();
153         final byte[] A_PAYLOAD = "XAAY".getBytes();
154         final Path target = Files.createTempFile(dir, "scattertest", ".zip");
155         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
156             final Path scatterFile = fileSystem.getPath("scattertest.notzip");
157             try (ScatterZipOutputStream scatterZipOutputStream = ScatterZipOutputStream.pathBased(scatterFile)) {
158 
159                 final ZipArchiveEntry zab = new ZipArchiveEntry("b.txt");
160                 zab.setMethod(ZipEntry.DEFLATED);
161                 final ByteArrayInputStream payload = new ByteArrayInputStream(B_PAYLOAD);
162                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zab, createPayloadSupplier(payload)));
163 
164                 final ZipArchiveEntry zae = new ZipArchiveEntry("a.txt");
165                 zae.setMethod(ZipEntry.DEFLATED);
166                 final ByteArrayInputStream payload1 = new ByteArrayInputStream(A_PAYLOAD);
167                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zae, createPayloadSupplier(payload1)));
168 
169                 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(target)) {
170                     scatterZipOutputStream.writeTo(outputStream);
171                 }
172             }
173 
174             try (ZipFile zf = ZipFile.builder().setPath(target).get()) {
175                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
176                 assertEquals(8, b_entry.getSize());
177                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
178                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
179                 }
180 
181                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
182                 assertEquals(4, a_entry.getSize());
183                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
184                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
185                 }
186             }
187         } finally {
188             PathUtils.delete(target);
189         }
190     }
191 
192     @Test
193     public void testScatterFileWithCompressionAndTargetInMemory() throws IOException {
194         final byte[] B_PAYLOAD = "RBBBBBBS".getBytes();
195         final byte[] A_PAYLOAD = "XAAY".getBytes();
196         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
197             final Path target = fileSystem.getPath("scattertest.zip");
198             final Path scatterFile = fileSystem.getPath("scattertest.notzip");
199             try (ScatterZipOutputStream scatterZipOutputStream = ScatterZipOutputStream.pathBased(scatterFile, Deflater.BEST_COMPRESSION)) {
200 
201                 final ZipArchiveEntry zab = new ZipArchiveEntry("b.txt");
202                 zab.setMethod(ZipEntry.DEFLATED);
203                 final ByteArrayInputStream payload = new ByteArrayInputStream(B_PAYLOAD);
204                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zab, createPayloadSupplier(payload)));
205 
206                 final ZipArchiveEntry zae = new ZipArchiveEntry("a.txt");
207                 zae.setMethod(ZipEntry.DEFLATED);
208                 final ByteArrayInputStream payload1 = new ByteArrayInputStream(A_PAYLOAD);
209                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zae, createPayloadSupplier(payload1)));
210 
211                 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(target)) {
212                     scatterZipOutputStream.writeTo(outputStream);
213                 }
214             }
215             try (ZipFile zf = ZipFile.builder().setPath(target).get()) {
216                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
217                 assertEquals(8, b_entry.getSize());
218                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
219                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
220                 }
221 
222                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
223                 assertEquals(4, a_entry.getSize());
224                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
225                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
226                 }
227             }
228 
229             try (ZipFile zf = new ZipFile(Files.newByteChannel(target, StandardOpenOption.READ), target.getFileName().toString(), StandardCharsets.UTF_8.name(),
230                     true)) {
231                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
232                 assertEquals(8, b_entry.getSize());
233                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
234                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
235                 }
236 
237                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
238                 assertEquals(4, a_entry.getSize());
239                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
240                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
241                 }
242             }
243 
244             try (ZipFile zf = new ZipFile(Files.newByteChannel(target, StandardOpenOption.READ), target.getFileName().toString(), StandardCharsets.UTF_8.name(),
245                     true, false)) {
246                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
247                 assertEquals(8, b_entry.getSize());
248                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
249                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
250                 }
251 
252                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
253                 assertEquals(4, a_entry.getSize());
254                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
255                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
256                 }
257             }
258 
259         }
260     }
261 
262     @Test
263     public void testScatterFileWithCompressionInMemory() throws IOException {
264         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
265             final Path scatterFile = fileSystem.getPath("scattertest.notzip");
266             final Path target = Files.createTempFile(dir, "scattertest", ".zip");
267             final byte[] B_PAYLOAD = "RBBBBBBS".getBytes();
268             final byte[] A_PAYLOAD = "XAAY".getBytes();
269             try (ScatterZipOutputStream scatterZipOutputStream = ScatterZipOutputStream.pathBased(scatterFile, Deflater.BEST_COMPRESSION)) {
270 
271                 final ZipArchiveEntry zab = new ZipArchiveEntry("b.txt");
272                 zab.setMethod(ZipEntry.DEFLATED);
273                 final ByteArrayInputStream payload = new ByteArrayInputStream(B_PAYLOAD);
274                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zab, createPayloadSupplier(payload)));
275 
276                 final ZipArchiveEntry zae = new ZipArchiveEntry("a.txt");
277                 zae.setMethod(ZipEntry.DEFLATED);
278                 final ByteArrayInputStream payload1 = new ByteArrayInputStream(A_PAYLOAD);
279                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zae, createPayloadSupplier(payload1)));
280 
281                 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(target)) {
282                     scatterZipOutputStream.writeTo(outputStream);
283                 }
284             }
285 
286             try (ZipFile zf = ZipFile.builder().setPath(target).get()) {
287                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
288                 assertEquals(8, b_entry.getSize());
289                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
290                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
291                 }
292 
293                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
294                 assertEquals(4, a_entry.getSize());
295                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
296                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
297                 }
298             }
299         }
300 
301     }
302 
303     @Test
304     public void testZipFileInMemory() throws IOException {
305         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
306             final Path scatterFile = fileSystem.getPath("scattertest.notzip");
307             final Path target = fileSystem.getPath("scattertest.zip");
308             final byte[] B_PAYLOAD = "RBBBBBBS".getBytes();
309             final byte[] A_PAYLOAD = "XAAY".getBytes();
310             try (ScatterZipOutputStream scatterZipOutputStream = ScatterZipOutputStream.pathBased(scatterFile, Deflater.BEST_COMPRESSION)) {
311 
312                 final ZipArchiveEntry zab = new ZipArchiveEntry("b.txt");
313                 zab.setMethod(ZipEntry.DEFLATED);
314                 final ByteArrayInputStream payload = new ByteArrayInputStream(B_PAYLOAD);
315                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zab, createPayloadSupplier(payload)));
316 
317                 final ZipArchiveEntry zae = new ZipArchiveEntry("a.txt");
318                 zae.setMethod(ZipEntry.DEFLATED);
319                 final ByteArrayInputStream payload1 = new ByteArrayInputStream(A_PAYLOAD);
320                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zae, createPayloadSupplier(payload1)));
321 
322                 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(target)) {
323                     scatterZipOutputStream.writeTo(outputStream);
324                 }
325             }
326 
327             try (ZipFile zf = new ZipFile(target)) {
328                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
329                 assertEquals(8, b_entry.getSize());
330                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
331                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
332                 }
333 
334                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
335                 assertEquals(4, a_entry.getSize());
336                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
337                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
338                 }
339             }
340         }
341     }
342 
343     @Test
344     public void testZipFromMemoryFileSystemFile() throws IOException, NoSuchAlgorithmException {
345         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
346             final Path textFileInMemSys = fileSystem.getPath("test.txt");
347             final byte[] bytes = new byte[100 * 1024];
348             SecureRandom.getInstanceStrong().nextBytes(bytes);
349             Files.write(textFileInMemSys, bytes);
350 
351             final Path zipInLocalSys = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
352             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInLocalSys.toFile())) {
353                 final ZipArchiveEntry entry = new ZipArchiveEntry(textFileInMemSys, textFileInMemSys.getFileName().toString());
354                 entry.setSize(Files.size(textFileInMemSys));
355                 zipOut.putArchiveEntry(entry);
356 
357                 Files.copy(textFileInMemSys, zipOut);
358                 zipOut.closeArchiveEntry();
359                 zipOut.finish();
360                 assertEquals(Files.size(zipInLocalSys), zipOut.getBytesWritten());
361             }
362         }
363     }
364 
365     @Test
366     public void testZipFromMemoryFileSystemOutputStream() throws IOException, ArchiveException {
367         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
368             final Path p = fileSystem.getPath("test.txt");
369             Files.write(p, "Test".getBytes(UTF_8));
370 
371             final Path f = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
372             try (OutputStream out = Files.newOutputStream(f);
373                     ArchiveOutputStream<ZipArchiveEntry> zipOut = ArchiveStreamFactory.DEFAULT.createArchiveOutputStream(ArchiveStreamFactory.ZIP, out)) {
374                 final ZipArchiveEntry entry = new ZipArchiveEntry(p, p.getFileName().toString());
375                 entry.setSize(Files.size(p));
376                 zipOut.putArchiveEntry(entry);
377 
378                 Files.copy(p, zipOut);
379                 zipOut.closeArchiveEntry();
380                 assertEquals(Files.size(f), zipOut.getBytesWritten());
381             }
382         }
383     }
384 
385     @Test
386     public void testZipFromMemoryFileSystemPath() throws IOException, NoSuchAlgorithmException {
387         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
388             final Path textFileInMemSys = fileSystem.getPath("test.txt");
389             final byte[] bytes = new byte[100 * 1024];
390             SecureRandom.getInstanceStrong().nextBytes(bytes);
391             Files.write(textFileInMemSys, bytes);
392 
393             final Path zipInLocalSys = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
394             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInLocalSys)) {
395                 final ZipArchiveEntry entry = new ZipArchiveEntry(textFileInMemSys, textFileInMemSys.getFileName().toString());
396                 entry.setSize(Files.size(textFileInMemSys));
397                 zipOut.putArchiveEntry(entry);
398 
399                 Files.copy(textFileInMemSys, zipOut);
400                 zipOut.closeArchiveEntry();
401                 zipOut.finish();
402                 assertEquals(Files.size(zipInLocalSys), zipOut.getBytesWritten());
403             }
404         }
405     }
406 
407     @Test
408     public void testZipFromMemoryFileSystemSeekableByteChannel() throws IOException, NoSuchAlgorithmException {
409         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
410             final Path textFileInMemSys = fileSystem.getPath("test.txt");
411             final byte[] bytes = new byte[100 * 1024];
412             SecureRandom.getInstanceStrong().nextBytes(bytes);
413             Files.write(textFileInMemSys, bytes);
414 
415             final Path zipInLocalSys = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
416             try (SeekableByteChannel byteChannel = Files.newByteChannel(zipInLocalSys,
417                     EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING));
418                     ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(byteChannel)) {
419                 final ZipArchiveEntry entry = new ZipArchiveEntry(textFileInMemSys, textFileInMemSys.getFileName().toString());
420                 entry.setSize(Files.size(textFileInMemSys));
421                 zipOut.putArchiveEntry(entry);
422 
423                 Files.copy(textFileInMemSys, zipOut);
424                 zipOut.closeArchiveEntry();
425                 zipOut.finish();
426                 assertEquals(Files.size(zipInLocalSys), zipOut.getBytesWritten());
427             }
428         }
429     }
430 
431     @Test
432     public void testZipFromMemoryFileSystemSplitFile() throws IOException, NoSuchAlgorithmException {
433         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
434             final Path textFileInMemSys = fileSystem.getPath("test.txt");
435             final byte[] bytes = new byte[100 * 1024];
436             SecureRandom.getInstanceStrong().nextBytes(bytes);
437             Files.write(textFileInMemSys, bytes);
438 
439             final Path zipInLocalSys = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
440             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInLocalSys.toFile(), 64 * 1024L)) {
441                 final ZipArchiveEntry entry = new ZipArchiveEntry(textFileInMemSys, textFileInMemSys.getFileName().toString());
442                 entry.setSize(Files.size(textFileInMemSys));
443                 zipOut.putArchiveEntry(entry);
444 
445                 Files.copy(textFileInMemSys, zipOut);
446                 zipOut.closeArchiveEntry();
447                 zipOut.finish();
448                 List<Path> splitZips;
449                 try (Stream<Path> paths = Files.walk(dir, 1)) {
450                     splitZips = paths.filter(Files::isRegularFile).peek(path -> println("Found: " + path.toAbsolutePath())).collect(Collectors.toList());
451                 }
452                 assertEquals(splitZips.size(), 2);
453                 assertEquals(Files.size(splitZips.get(0)) + Files.size(splitZips.get(1)) - 4, zipOut.getBytesWritten());
454             }
455         }
456 
457     }
458 
459     @Test
460     public void testZipToMemoryFileSystemOutputStream() throws IOException, ArchiveException {
461         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
462             final Path p = fileSystem.getPath("target.zip");
463 
464             try (OutputStream out = Files.newOutputStream(p);
465                     ArchiveOutputStream<ZipArchiveEntry> zipOut = ArchiveStreamFactory.DEFAULT.createArchiveOutputStream(ArchiveStreamFactory.ZIP, out)) {
466                 final String content = "Test";
467                 final ZipArchiveEntry entry = new ZipArchiveEntry("test.txt");
468                 entry.setSize(content.length());
469                 zipOut.putArchiveEntry(entry);
470 
471                 zipOut.write("Test".getBytes(UTF_8));
472                 zipOut.closeArchiveEntry();
473 
474                 assertTrue(Files.exists(p));
475                 assertEquals(Files.size(p), zipOut.getBytesWritten());
476             }
477         }
478     }
479 
480     @Test
481     public void testZipToMemoryFileSystemPath() throws IOException {
482         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
483             final Path zipInMemSys = fileSystem.getPath("target.zip");
484 
485             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInMemSys)) {
486                 final String content = "Test";
487                 final ZipArchiveEntry entry = new ZipArchiveEntry("test.txt");
488                 entry.setSize(content.length());
489                 zipOut.putArchiveEntry(entry);
490 
491                 zipOut.write("Test".getBytes(UTF_8));
492                 zipOut.closeArchiveEntry();
493 
494                 assertTrue(Files.exists(zipInMemSys));
495                 assertEquals(Files.size(zipInMemSys), zipOut.getBytesWritten());
496             }
497         }
498     }
499 
500     @Test
501     public void testZipToMemoryFileSystemSeekableByteChannel() throws IOException {
502         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
503             final Path zipInMemSys = fileSystem.getPath("target.zip");
504 
505             try (SeekableByteChannel byteChannel = Files.newByteChannel(zipInMemSys,
506                     EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE_NEW));
507                     ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(byteChannel)) {
508                 final String content = "Test";
509                 final ZipArchiveEntry entry = new ZipArchiveEntry("test.txt");
510                 entry.setSize(content.length());
511                 zipOut.putArchiveEntry(entry);
512 
513                 zipOut.write("Test".getBytes(UTF_8));
514                 zipOut.closeArchiveEntry();
515 
516                 assertTrue(Files.exists(zipInMemSys));
517                 assertEquals(Files.size(zipInMemSys), zipOut.getBytesWritten());
518             }
519         }
520     }
521 
522     @Test
523     public void testZipToMemoryFileSystemSplitPath() throws IOException, NoSuchAlgorithmException {
524         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
525             final Path zipInMemSys = fileSystem.getPath("target.zip");
526             final byte[] bytes = new byte[100 * 1024];
527             SecureRandom.getInstanceStrong().nextBytes(bytes);
528 
529             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInMemSys, 64 * 1024L)) {
530                 final ZipArchiveEntry entry = new ZipArchiveEntry("test.txt");
531                 entry.setSize(bytes.length);
532                 zipOut.putArchiveEntry(entry);
533 
534                 zipOut.write(bytes);
535 
536                 zipOut.closeArchiveEntry();
537                 zipOut.finish();
538 
539                 List<Path> splitZips;
540                 try (Stream<Path> paths = Files.walk(fileSystem.getPath("."), 1)) {
541                     splitZips = paths.filter(Files::isRegularFile).peek(path -> println("Found: " + path.toAbsolutePath())).collect(Collectors.toList());
542                 }
543                 assertEquals(splitZips.size(), 2);
544                 assertEquals(Files.size(splitZips.get(0)) + Files.size(splitZips.get(1)) - 4, zipOut.getBytesWritten());
545             }
546         }
547 
548     }
549 }