From a127e7644e9166d2eba73aca0e4fef901d4dcf02 Mon Sep 17 00:00:00 2001
From: Manfred <77407079+manfred106@users.noreply.github.com>
Date: Mon, 30 Oct 2023 00:56:52 +0000
Subject: [PATCH] BAEL-6804: Difference Between ZipFile and ZipInputStream in
Java (#15039)
* BAEL-6804: Difference Between ZipFile and ZipInputStream in Java
* BAEL-6804: Difference Between ZipFile and ZipInputStream in Java
- use 2-space indents for line continuations
---
core-java-modules/core-java-io-5/pom.xml | 16 +++
.../java/com/baeldung/zip/ZipBenchmark.java | 112 ++++++++++++++++++
.../com/baeldung/zip/ZipSampleFileStore.java | 70 +++++++++++
.../java/com/baeldung/zip/ZipUnitTest.java | 83 +++++++++++++
4 files changed, 281 insertions(+)
create mode 100644 core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipBenchmark.java
create mode 100644 core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipSampleFileStore.java
create mode 100644 core-java-modules/core-java-io-5/src/test/java/com/baeldung/zip/ZipUnitTest.java
diff --git a/core-java-modules/core-java-io-5/pom.xml b/core-java-modules/core-java-io-5/pom.xml
index 11116b071c..5c987a82e1 100644
--- a/core-java-modules/core-java-io-5/pom.xml
+++ b/core-java-modules/core-java-io-5/pom.xml
@@ -35,6 +35,21 @@
simplemagic
${simplemagic.version}
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+
@@ -62,5 +77,6 @@
0.1.5
6.2.1
1.17
+ 1.37
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipBenchmark.java b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipBenchmark.java
new file mode 100644
index 0000000000..30ec1522a2
--- /dev/null
+++ b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipBenchmark.java
@@ -0,0 +1,112 @@
+package com.baeldung.zip;
+
+import java.io.*;
+import java.util.concurrent.TimeUnit;
+import java.util.*;
+import java.util.zip.*;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@Warmup(iterations = 1, time = 2, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Fork(value = 1)
+public class ZipBenchmark {
+
+ public static final int NUM_OF_FILES = 10;
+ public static final int DATA_SIZE = 204800;
+
+ @State(Scope.Thread)
+ public static class SourceState {
+
+ public File compressedFile;
+
+ @Setup(Level.Trial)
+ public void setup() throws IOException {
+ ZipSampleFileStore sampleFileStore = new ZipSampleFileStore(NUM_OF_FILES, DATA_SIZE);
+ compressedFile = sampleFileStore.getFile();
+ }
+
+ @TearDown(Level.Trial)
+ public void cleanup() {
+ if (compressedFile.exists()) {
+ compressedFile.delete();
+ }
+ }
+ }
+
+ @Benchmark
+ public static void readAllEntriesByZipFile(SourceState sourceState, Blackhole blackhole) throws IOException {
+
+ try (ZipFile zipFile = new ZipFile(sourceState.compressedFile)) {
+ Enumeration extends ZipEntry> zipEntries = zipFile.entries();
+ while (zipEntries.hasMoreElements()) {
+ ZipEntry zipEntry = zipEntries.nextElement();
+ try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry))) {
+ blackhole.consume(ZipSampleFileStore.getString(inputStream));
+ }
+ }
+ }
+ }
+
+ @Benchmark
+ public static void readAllEntriesByZipInputStream(SourceState sourceState, Blackhole blackhole) throws IOException {
+
+ try (
+ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceState.compressedFile));
+ ZipInputStream zipInputStream = new ZipInputStream(bis)
+ ) {
+ ZipEntry entry;
+ while ((entry = zipInputStream.getNextEntry()) != null) {
+ blackhole.consume(ZipSampleFileStore.getString(zipInputStream));
+ }
+ }
+ }
+
+ @Benchmark
+ public static void readLastEntryByZipFile(SourceState sourceState, Blackhole blackhole) throws IOException {
+
+ try (ZipFile zipFile = new ZipFile(sourceState.compressedFile)) {
+ ZipEntry zipEntry = zipFile.getEntry(getLastEntryName());
+ try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry))) {
+ blackhole.consume(ZipSampleFileStore.getString(inputStream));
+ }
+ }
+ }
+
+ @Benchmark
+ public static void readLastEntryByZipInputStream(SourceState sourceState, Blackhole blackhole) throws IOException {
+
+ try (
+ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceState.compressedFile));
+ ZipInputStream zipInputStream = new ZipInputStream(bis)
+ ) {
+ ZipEntry entry;
+ while ((entry = zipInputStream.getNextEntry()) != null) {
+ if (Objects.equals(entry.getName(), getLastEntryName())){
+ blackhole.consume(ZipSampleFileStore.getString(zipInputStream));
+ }
+ }
+ }
+ }
+
+ private static String getLastEntryName() {
+ return String.format(ZipSampleFileStore.ENTRY_NAME_PATTERN, NUM_OF_FILES);
+ }
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder()
+ .include(ZipBenchmark.class.getSimpleName()).threads(1)
+ .shouldFailOnError(true)
+ .shouldDoGC(true)
+ .jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipSampleFileStore.java b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipSampleFileStore.java
new file mode 100644
index 0000000000..389f082ff1
--- /dev/null
+++ b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipSampleFileStore.java
@@ -0,0 +1,70 @@
+package com.baeldung.zip;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.commons.io.IOUtils;
+
+public class ZipSampleFileStore {
+
+ public static final String ENTRY_NAME_PATTERN = "str-data-%s.txt";
+ private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
+
+ private final File file;
+ private final List dataList;
+
+ public ZipSampleFileStore(int numOfFiles, int fileSize) throws IOException {
+
+ dataList = new ArrayList<>(numOfFiles);
+ file = File.createTempFile("zip-sample", "");
+
+ try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file))) {
+
+ for (int idx=0; idx<=numOfFiles; idx++) {
+
+ byte[] data = createRandomStringInByte(fileSize);
+ dataList.add(new String(data, DEFAULT_ENCODING));
+
+ ZipEntry entry = new ZipEntry(String.format(ENTRY_NAME_PATTERN, idx));
+ zos.putNextEntry(entry);
+ zos.write(data);
+ zos.closeEntry();
+ }
+ }
+ }
+
+ public static byte[] createRandomStringInByte(int size) {
+ Random random = new Random();
+ byte[] data = new byte[size];
+ for (int n = 0; n < data.length; n++) {
+ char randomChar;
+ int choice = random.nextInt(2); // 0 for uppercase, 1 for lowercase
+ if (choice == 0) {
+ randomChar = (char) ('A' + random.nextInt(26)); // 'A' to 'Z'
+ } else {
+ randomChar = (char) ('a' + random.nextInt(26)); // 'a' to 'z'
+ }
+ data[n] = (byte) randomChar;
+ }
+ return data;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public List getDataList() {
+ return dataList;
+ }
+
+ public static String getString(InputStream inputStream) throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ IOUtils.copy(inputStream, byteArrayOutputStream);
+ return byteArrayOutputStream.toString(DEFAULT_ENCODING);
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-5/src/test/java/com/baeldung/zip/ZipUnitTest.java b/core-java-modules/core-java-io-5/src/test/java/com/baeldung/zip/ZipUnitTest.java
new file mode 100644
index 0000000000..1d4d76dc41
--- /dev/null
+++ b/core-java-modules/core-java-io-5/src/test/java/com/baeldung/zip/ZipUnitTest.java
@@ -0,0 +1,83 @@
+package com.baeldung.zip;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+import org.junit.*;
+
+public class ZipUnitTest {
+
+ private static File compressedFile;
+ private static List dataList = new ArrayList<>();
+
+ @BeforeClass
+ public static void prepareData() throws IOException {
+ ZipSampleFileStore sampleFileStore = new ZipSampleFileStore(ZipBenchmark.NUM_OF_FILES, ZipBenchmark.DATA_SIZE);
+ compressedFile = sampleFileStore.getFile();
+ dataList = sampleFileStore.getDataList();
+ }
+
+ @Test
+ public void whenCreateZipFile_thenCompressedSizeShouldBeLessThanOriginal() throws IOException {
+ byte[] data = ZipSampleFileStore.createRandomStringInByte(10240);
+ File file = File.createTempFile("zip-temp", "");
+
+ try (
+ BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
+ ZipOutputStream zos = new ZipOutputStream(bos)
+ ) {
+ ZipEntry zipEntry = new ZipEntry("zip-entry.txt");
+ zos.putNextEntry(zipEntry);
+ zos.write(data);
+ zos.closeEntry();
+
+ assertThat(file.length()).isLessThan(data.length);
+ }
+ finally {
+ file.delete();
+ }
+ }
+
+ @Test
+ public void whenReadAllEntriesViaZipFile_thenDataIsEqualtoTheSource() throws IOException {
+
+ try (ZipFile zipFile = new ZipFile(compressedFile)) {
+ Enumeration extends ZipEntry> entries = zipFile.entries();
+ List extends ZipEntry> entryList = Collections.list(entries);
+
+ for (int idx=0; idx