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 ignored) {
87                      // ignored
88                  }
89              });
90          }
91      }
92  
93      @Test
94      public void testForPathsReturnCorrectClassInMemory() throws IOException {
95          final Path firstFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
96          final Path secondFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
97          final Path lastFile = getPath("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
98          final byte[] firstBytes = Files.readAllBytes(firstFile);
99          final byte[] secondBytes = Files.readAllBytes(secondFile);
100         final byte[] lastBytes = Files.readAllBytes(lastFile);
101         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
102             Files.write(fileSystem.getPath("split_zip_created_by_zip.z01"), firstBytes);
103             Files.write(fileSystem.getPath("split_zip_created_by_zip.z02"), secondBytes);
104             Files.write(fileSystem.getPath("split_zip_created_by_zip.zip"), lastBytes);
105             final ArrayList<Path> list = new ArrayList<>();
106             list.add(firstFile);
107             list.add(secondFile);
108 
109             try (SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forPaths(lastFile, list)) {
110                 assertTrue(channel instanceof ZipSplitReadOnlySeekableByteChannel);
111             }
112 
113             try (SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.forPaths(firstFile, secondFile, lastFile)) {
114                 assertTrue(channel instanceof ZipSplitReadOnlySeekableByteChannel);
115             }
116         }
117     }
118 
119     @Test
120     public void testPositionToSomeZipSplitSegmentInMemory() throws IOException {
121         final byte[] firstBytes = AbstractTest.readAllBytes("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z01");
122         final byte[] secondBytes = AbstractTest.readAllBytes("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.z02");
123         final byte[] lastBytes = AbstractTest.readAllBytes("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
124         final int firstFileSize = firstBytes.length;
125         final int secondFileSize = secondBytes.length;
126         final int lastFileSize = lastBytes.length;
127 
128         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
129             final Path lastMemoryPath = fileSystem.getPath("split_zip_created_by_zip.zip");
130             Files.write(fileSystem.getPath("split_zip_created_by_zip.z01"), firstBytes);
131             Files.write(fileSystem.getPath("split_zip_created_by_zip.z02"), secondBytes);
132             Files.write(lastMemoryPath, lastBytes);
133             final Random random = new Random();
134             final int randomDiskNumber = random.nextInt(3);
135             final int randomOffset = randomDiskNumber < 2 ? random.nextInt(firstFileSize) : random.nextInt(lastFileSize);
136 
137             try (ZipSplitReadOnlySeekableByteChannel channel = (ZipSplitReadOnlySeekableByteChannel) ZipSplitReadOnlySeekableByteChannel
138                     .buildFromLastSplitSegment(lastMemoryPath)) {
139                 channel.position(randomDiskNumber, randomOffset);
140                 long expectedPosition = randomOffset;
141 
142                 expectedPosition += randomDiskNumber > 0 ? firstFileSize : 0;
143                 expectedPosition += randomDiskNumber > 1 ? secondFileSize : 0;
144 
145                 assertEquals(expectedPosition, channel.position());
146             }
147         }
148 
149     }
150 
151     @Test
152     public void testScatterFileInMemory() throws IOException {
153         final byte[] B_PAYLOAD = "RBBBBBBS".getBytes();
154         final byte[] A_PAYLOAD = "XAAY".getBytes();
155         final Path target = Files.createTempFile(dir, "scattertest", ".zip");
156         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
157             final Path scatterFile = fileSystem.getPath("scattertest.notzip");
158             try (ScatterZipOutputStream scatterZipOutputStream = ScatterZipOutputStream.pathBased(scatterFile)) {
159 
160                 final ZipArchiveEntry zab = new ZipArchiveEntry("b.txt");
161                 zab.setMethod(ZipEntry.DEFLATED);
162                 final ByteArrayInputStream payload = new ByteArrayInputStream(B_PAYLOAD);
163                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zab, createPayloadSupplier(payload)));
164 
165                 final ZipArchiveEntry zae = new ZipArchiveEntry("a.txt");
166                 zae.setMethod(ZipEntry.DEFLATED);
167                 final ByteArrayInputStream payload1 = new ByteArrayInputStream(A_PAYLOAD);
168                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zae, createPayloadSupplier(payload1)));
169 
170                 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(target)) {
171                     scatterZipOutputStream.writeTo(outputStream);
172                 }
173             }
174 
175             try (ZipFile zf = ZipFile.builder().setPath(target).get()) {
176                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
177                 assertEquals(8, b_entry.getSize());
178                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
179                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
180                 }
181 
182                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
183                 assertEquals(4, a_entry.getSize());
184                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
185                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
186                 }
187             }
188         } finally {
189             PathUtils.delete(target);
190         }
191     }
192 
193     @Test
194     public void testScatterFileWithCompressionAndTargetInMemory() throws IOException {
195         final byte[] B_PAYLOAD = "RBBBBBBS".getBytes();
196         final byte[] A_PAYLOAD = "XAAY".getBytes();
197         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
198             final Path target = fileSystem.getPath("scattertest.zip");
199             final Path scatterFile = fileSystem.getPath("scattertest.notzip");
200             try (ScatterZipOutputStream scatterZipOutputStream = ScatterZipOutputStream.pathBased(scatterFile, Deflater.BEST_COMPRESSION)) {
201 
202                 final ZipArchiveEntry zab = new ZipArchiveEntry("b.txt");
203                 zab.setMethod(ZipEntry.DEFLATED);
204                 final ByteArrayInputStream payload = new ByteArrayInputStream(B_PAYLOAD);
205                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zab, createPayloadSupplier(payload)));
206 
207                 final ZipArchiveEntry zae = new ZipArchiveEntry("a.txt");
208                 zae.setMethod(ZipEntry.DEFLATED);
209                 final ByteArrayInputStream payload1 = new ByteArrayInputStream(A_PAYLOAD);
210                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zae, createPayloadSupplier(payload1)));
211 
212                 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(target)) {
213                     scatterZipOutputStream.writeTo(outputStream);
214                 }
215             }
216             try (ZipFile zf = ZipFile.builder().setPath(target).get()) {
217                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
218                 assertEquals(8, b_entry.getSize());
219                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
220                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
221                 }
222 
223                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
224                 assertEquals(4, a_entry.getSize());
225                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
226                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
227                 }
228             }
229 
230             try (ZipFile zf = new ZipFile(Files.newByteChannel(target, StandardOpenOption.READ), target.getFileName().toString(), StandardCharsets.UTF_8.name(),
231                     true)) {
232                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
233                 assertEquals(8, b_entry.getSize());
234                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
235                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
236                 }
237 
238                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
239                 assertEquals(4, a_entry.getSize());
240                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
241                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
242                 }
243             }
244 
245             try (ZipFile zf = new ZipFile(Files.newByteChannel(target, StandardOpenOption.READ), target.getFileName().toString(), StandardCharsets.UTF_8.name(),
246                     true, false)) {
247                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
248                 assertEquals(8, b_entry.getSize());
249                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
250                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
251                 }
252 
253                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
254                 assertEquals(4, a_entry.getSize());
255                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
256                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
257                 }
258             }
259 
260         }
261     }
262 
263     @Test
264     public void testScatterFileWithCompressionInMemory() throws IOException {
265         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
266             final Path scatterFile = fileSystem.getPath("scattertest.notzip");
267             final Path target = Files.createTempFile(dir, "scattertest", ".zip");
268             final byte[] B_PAYLOAD = "RBBBBBBS".getBytes();
269             final byte[] A_PAYLOAD = "XAAY".getBytes();
270             try (ScatterZipOutputStream scatterZipOutputStream = ScatterZipOutputStream.pathBased(scatterFile, Deflater.BEST_COMPRESSION)) {
271 
272                 final ZipArchiveEntry zab = new ZipArchiveEntry("b.txt");
273                 zab.setMethod(ZipEntry.DEFLATED);
274                 final ByteArrayInputStream payload = new ByteArrayInputStream(B_PAYLOAD);
275                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zab, createPayloadSupplier(payload)));
276 
277                 final ZipArchiveEntry zae = new ZipArchiveEntry("a.txt");
278                 zae.setMethod(ZipEntry.DEFLATED);
279                 final ByteArrayInputStream payload1 = new ByteArrayInputStream(A_PAYLOAD);
280                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zae, createPayloadSupplier(payload1)));
281 
282                 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(target)) {
283                     scatterZipOutputStream.writeTo(outputStream);
284                 }
285             }
286 
287             try (ZipFile zf = ZipFile.builder().setPath(target).get()) {
288                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
289                 assertEquals(8, b_entry.getSize());
290                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
291                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
292                 }
293 
294                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
295                 assertEquals(4, a_entry.getSize());
296                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
297                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
298                 }
299             }
300         }
301 
302     }
303 
304     @Test
305     public void testZipFileInMemory() throws IOException {
306         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
307             final Path scatterFile = fileSystem.getPath("scattertest.notzip");
308             final Path target = fileSystem.getPath("scattertest.zip");
309             final byte[] B_PAYLOAD = "RBBBBBBS".getBytes();
310             final byte[] A_PAYLOAD = "XAAY".getBytes();
311             try (ScatterZipOutputStream scatterZipOutputStream = ScatterZipOutputStream.pathBased(scatterFile, Deflater.BEST_COMPRESSION)) {
312 
313                 final ZipArchiveEntry zab = new ZipArchiveEntry("b.txt");
314                 zab.setMethod(ZipEntry.DEFLATED);
315                 final ByteArrayInputStream payload = new ByteArrayInputStream(B_PAYLOAD);
316                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zab, createPayloadSupplier(payload)));
317 
318                 final ZipArchiveEntry zae = new ZipArchiveEntry("a.txt");
319                 zae.setMethod(ZipEntry.DEFLATED);
320                 final ByteArrayInputStream payload1 = new ByteArrayInputStream(A_PAYLOAD);
321                 scatterZipOutputStream.addArchiveEntry(createZipArchiveEntryRequest(zae, createPayloadSupplier(payload1)));
322 
323                 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(target)) {
324                     scatterZipOutputStream.writeTo(outputStream);
325                 }
326             }
327 
328             try (ZipFile zf = new ZipFile(target)) {
329                 final ZipArchiveEntry b_entry = zf.getEntries("b.txt").iterator().next();
330                 assertEquals(8, b_entry.getSize());
331                 try (InputStream inputStream = zf.getInputStream(b_entry)) {
332                     assertArrayEquals(B_PAYLOAD, IOUtils.toByteArray(inputStream));
333                 }
334 
335                 final ZipArchiveEntry a_entry = zf.getEntries("a.txt").iterator().next();
336                 assertEquals(4, a_entry.getSize());
337                 try (InputStream inputStream = zf.getInputStream(a_entry)) {
338                     assertArrayEquals(A_PAYLOAD, IOUtils.toByteArray(inputStream));
339                 }
340             }
341         }
342     }
343 
344     @Test
345     public void testZipFromMemoryFileSystemFile() throws IOException, NoSuchAlgorithmException {
346         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
347             final Path textFileInMemSys = fileSystem.getPath("test.txt");
348             final byte[] bytes = new byte[100 * 1024];
349             SecureRandom.getInstanceStrong().nextBytes(bytes);
350             Files.write(textFileInMemSys, bytes);
351 
352             final Path zipInLocalSys = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
353             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInLocalSys.toFile())) {
354                 final ZipArchiveEntry entry = new ZipArchiveEntry(textFileInMemSys, textFileInMemSys.getFileName().toString());
355                 entry.setSize(Files.size(textFileInMemSys));
356                 zipOut.putArchiveEntry(entry);
357 
358                 Files.copy(textFileInMemSys, zipOut);
359                 zipOut.closeArchiveEntry();
360                 zipOut.finish();
361                 assertEquals(Files.size(zipInLocalSys), zipOut.getBytesWritten());
362             }
363         }
364     }
365 
366     @Test
367     public void testZipFromMemoryFileSystemOutputStream() throws IOException, ArchiveException {
368         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
369             final Path p = fileSystem.getPath("test.txt");
370             Files.write(p, "Test".getBytes(UTF_8));
371 
372             final Path f = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
373             try (OutputStream out = Files.newOutputStream(f);
374                     ArchiveOutputStream<ZipArchiveEntry> zipOut = ArchiveStreamFactory.DEFAULT.createArchiveOutputStream(ArchiveStreamFactory.ZIP, out)) {
375                 final ZipArchiveEntry entry = new ZipArchiveEntry(p, p.getFileName().toString());
376                 entry.setSize(Files.size(p));
377                 zipOut.putArchiveEntry(entry);
378 
379                 Files.copy(p, zipOut);
380                 zipOut.closeArchiveEntry();
381                 assertEquals(Files.size(f), zipOut.getBytesWritten());
382             }
383         }
384     }
385 
386     @Test
387     public void testZipFromMemoryFileSystemPath() throws IOException, NoSuchAlgorithmException {
388         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
389             final Path textFileInMemSys = fileSystem.getPath("test.txt");
390             final byte[] bytes = new byte[100 * 1024];
391             SecureRandom.getInstanceStrong().nextBytes(bytes);
392             Files.write(textFileInMemSys, bytes);
393 
394             final Path zipInLocalSys = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
395             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInLocalSys)) {
396                 final ZipArchiveEntry entry = new ZipArchiveEntry(textFileInMemSys, textFileInMemSys.getFileName().toString());
397                 entry.setSize(Files.size(textFileInMemSys));
398                 zipOut.putArchiveEntry(entry);
399 
400                 Files.copy(textFileInMemSys, zipOut);
401                 zipOut.closeArchiveEntry();
402                 zipOut.finish();
403                 assertEquals(Files.size(zipInLocalSys), zipOut.getBytesWritten());
404             }
405         }
406     }
407 
408     @Test
409     public void testZipFromMemoryFileSystemSeekableByteChannel() throws IOException, NoSuchAlgorithmException {
410         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
411             final Path textFileInMemSys = fileSystem.getPath("test.txt");
412             final byte[] bytes = new byte[100 * 1024];
413             SecureRandom.getInstanceStrong().nextBytes(bytes);
414             Files.write(textFileInMemSys, bytes);
415 
416             final Path zipInLocalSys = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
417             try (SeekableByteChannel byteChannel = Files.newByteChannel(zipInLocalSys,
418                     EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING));
419                     ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(byteChannel)) {
420                 final ZipArchiveEntry entry = new ZipArchiveEntry(textFileInMemSys, textFileInMemSys.getFileName().toString());
421                 entry.setSize(Files.size(textFileInMemSys));
422                 zipOut.putArchiveEntry(entry);
423 
424                 Files.copy(textFileInMemSys, zipOut);
425                 zipOut.closeArchiveEntry();
426                 zipOut.finish();
427                 assertEquals(Files.size(zipInLocalSys), zipOut.getBytesWritten());
428             }
429         }
430     }
431 
432     @Test
433     public void testZipFromMemoryFileSystemSplitFile() throws IOException, NoSuchAlgorithmException {
434         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
435             final Path textFileInMemSys = fileSystem.getPath("test.txt");
436             final byte[] bytes = new byte[100 * 1024];
437             SecureRandom.getInstanceStrong().nextBytes(bytes);
438             Files.write(textFileInMemSys, bytes);
439 
440             final Path zipInLocalSys = Files.createTempFile(dir, "commons-compress-memoryfs", ".zip");
441             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInLocalSys.toFile(), 64 * 1024L)) {
442                 final ZipArchiveEntry entry = new ZipArchiveEntry(textFileInMemSys, textFileInMemSys.getFileName().toString());
443                 entry.setSize(Files.size(textFileInMemSys));
444                 zipOut.putArchiveEntry(entry);
445 
446                 Files.copy(textFileInMemSys, zipOut);
447                 zipOut.closeArchiveEntry();
448                 zipOut.finish();
449                 List<Path> splitZips;
450                 try (Stream<Path> paths = Files.walk(dir, 1)) {
451                     splitZips = paths.filter(Files::isRegularFile).peek(path -> println("Found: " + path.toAbsolutePath())).collect(Collectors.toList());
452                 }
453                 assertEquals(splitZips.size(), 2);
454                 assertEquals(Files.size(splitZips.get(0)) + Files.size(splitZips.get(1)) - 4, zipOut.getBytesWritten());
455             }
456         }
457 
458     }
459 
460     @Test
461     public void testZipToMemoryFileSystemOutputStream() throws IOException, ArchiveException {
462         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
463             final Path p = fileSystem.getPath("target.zip");
464 
465             try (OutputStream out = Files.newOutputStream(p);
466                     ArchiveOutputStream<ZipArchiveEntry> zipOut = ArchiveStreamFactory.DEFAULT.createArchiveOutputStream(ArchiveStreamFactory.ZIP, out)) {
467                 final String content = "Test";
468                 final ZipArchiveEntry entry = new ZipArchiveEntry("test.txt");
469                 entry.setSize(content.length());
470                 zipOut.putArchiveEntry(entry);
471 
472                 zipOut.write("Test".getBytes(UTF_8));
473                 zipOut.closeArchiveEntry();
474 
475                 assertTrue(Files.exists(p));
476                 assertEquals(Files.size(p), zipOut.getBytesWritten());
477             }
478         }
479     }
480 
481     @Test
482     public void testZipToMemoryFileSystemPath() throws IOException {
483         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
484             final Path zipInMemSys = fileSystem.getPath("target.zip");
485 
486             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInMemSys)) {
487                 final String content = "Test";
488                 final ZipArchiveEntry entry = new ZipArchiveEntry("test.txt");
489                 entry.setSize(content.length());
490                 zipOut.putArchiveEntry(entry);
491 
492                 zipOut.write("Test".getBytes(UTF_8));
493                 zipOut.closeArchiveEntry();
494 
495                 assertTrue(Files.exists(zipInMemSys));
496                 assertEquals(Files.size(zipInMemSys), zipOut.getBytesWritten());
497             }
498         }
499     }
500 
501     @Test
502     public void testZipToMemoryFileSystemSeekableByteChannel() throws IOException {
503         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
504             final Path zipInMemSys = fileSystem.getPath("target.zip");
505 
506             try (SeekableByteChannel byteChannel = Files.newByteChannel(zipInMemSys,
507                     EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE_NEW));
508                     ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(byteChannel)) {
509                 final String content = "Test";
510                 final ZipArchiveEntry entry = new ZipArchiveEntry("test.txt");
511                 entry.setSize(content.length());
512                 zipOut.putArchiveEntry(entry);
513 
514                 zipOut.write("Test".getBytes(UTF_8));
515                 zipOut.closeArchiveEntry();
516 
517                 assertTrue(Files.exists(zipInMemSys));
518                 assertEquals(Files.size(zipInMemSys), zipOut.getBytesWritten());
519             }
520         }
521     }
522 
523     @Test
524     public void testZipToMemoryFileSystemSplitPath() throws IOException, NoSuchAlgorithmException {
525         try (FileSystem fileSystem = MemoryFileSystemBuilder.newLinux().build()) {
526             final Path zipInMemSys = fileSystem.getPath("target.zip");
527             final byte[] bytes = new byte[100 * 1024];
528             SecureRandom.getInstanceStrong().nextBytes(bytes);
529 
530             try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(zipInMemSys, 64 * 1024L)) {
531                 final ZipArchiveEntry entry = new ZipArchiveEntry("test.txt");
532                 entry.setSize(bytes.length);
533                 zipOut.putArchiveEntry(entry);
534 
535                 zipOut.write(bytes);
536 
537                 zipOut.closeArchiveEntry();
538                 zipOut.finish();
539 
540                 List<Path> splitZips;
541                 try (Stream<Path> paths = Files.walk(fileSystem.getPath("."), 1)) {
542                     splitZips = paths.filter(Files::isRegularFile).peek(path -> println("Found: " + path.toAbsolutePath())).collect(Collectors.toList());
543                 }
544                 assertEquals(splitZips.size(), 2);
545                 assertEquals(Files.size(splitZips.get(0)) + Files.size(splitZips.get(1)) - 4, zipOut.getBytesWritten());
546             }
547         }
548 
549     }
550 }