Skip to content

Commit a127e76

Browse files
authored
BAEL-6804: Difference Between ZipFile and ZipInputStream in Java (eugenp#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
1 parent b7edd33 commit a127e76

4 files changed

Lines changed: 281 additions & 0 deletions

File tree

core-java-modules/core-java-io-5/pom.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,21 @@
3535
<artifactId>simplemagic</artifactId>
3636
<version>${simplemagic.version}</version>
3737
</dependency>
38+
<dependency>
39+
<groupId>commons-io</groupId>
40+
<artifactId>commons-io</artifactId>
41+
<version>${commons-io.version}</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.openjdk.jmh</groupId>
45+
<artifactId>jmh-core</artifactId>
46+
<version>${jmh.version}</version>
47+
</dependency>
48+
<dependency>
49+
<groupId>org.openjdk.jmh</groupId>
50+
<artifactId>jmh-generator-annprocess</artifactId>
51+
<version>${jmh.version}</version>
52+
</dependency>
3853
</dependencies>
3954

4055
<build>
@@ -62,5 +77,6 @@
6277
<jmime-magic.version>0.1.5</jmime-magic.version>
6378
<jodd-util.version>6.2.1</jodd-util.version>
6479
<simplemagic.version>1.17</simplemagic.version>
80+
<jmh.version>1.37</jmh.version>
6581
</properties>
6682
</project>
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.baeldung.zip;
2+
3+
import java.io.*;
4+
import java.util.concurrent.TimeUnit;
5+
import java.util.*;
6+
import java.util.zip.*;
7+
8+
import org.openjdk.jmh.annotations.*;
9+
import org.openjdk.jmh.infra.Blackhole;
10+
import org.openjdk.jmh.runner.Runner;
11+
import org.openjdk.jmh.runner.options.Options;
12+
import org.openjdk.jmh.runner.options.OptionsBuilder;
13+
14+
@State(Scope.Benchmark)
15+
@BenchmarkMode(Mode.AverageTime)
16+
@Warmup(iterations = 1, time = 2, timeUnit = TimeUnit.SECONDS)
17+
@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
18+
@OutputTimeUnit(TimeUnit.MILLISECONDS)
19+
@Fork(value = 1)
20+
public class ZipBenchmark {
21+
22+
public static final int NUM_OF_FILES = 10;
23+
public static final int DATA_SIZE = 204800;
24+
25+
@State(Scope.Thread)
26+
public static class SourceState {
27+
28+
public File compressedFile;
29+
30+
@Setup(Level.Trial)
31+
public void setup() throws IOException {
32+
ZipSampleFileStore sampleFileStore = new ZipSampleFileStore(NUM_OF_FILES, DATA_SIZE);
33+
compressedFile = sampleFileStore.getFile();
34+
}
35+
36+
@TearDown(Level.Trial)
37+
public void cleanup() {
38+
if (compressedFile.exists()) {
39+
compressedFile.delete();
40+
}
41+
}
42+
}
43+
44+
@Benchmark
45+
public static void readAllEntriesByZipFile(SourceState sourceState, Blackhole blackhole) throws IOException {
46+
47+
try (ZipFile zipFile = new ZipFile(sourceState.compressedFile)) {
48+
Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
49+
while (zipEntries.hasMoreElements()) {
50+
ZipEntry zipEntry = zipEntries.nextElement();
51+
try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry))) {
52+
blackhole.consume(ZipSampleFileStore.getString(inputStream));
53+
}
54+
}
55+
}
56+
}
57+
58+
@Benchmark
59+
public static void readAllEntriesByZipInputStream(SourceState sourceState, Blackhole blackhole) throws IOException {
60+
61+
try (
62+
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceState.compressedFile));
63+
ZipInputStream zipInputStream = new ZipInputStream(bis)
64+
) {
65+
ZipEntry entry;
66+
while ((entry = zipInputStream.getNextEntry()) != null) {
67+
blackhole.consume(ZipSampleFileStore.getString(zipInputStream));
68+
}
69+
}
70+
}
71+
72+
@Benchmark
73+
public static void readLastEntryByZipFile(SourceState sourceState, Blackhole blackhole) throws IOException {
74+
75+
try (ZipFile zipFile = new ZipFile(sourceState.compressedFile)) {
76+
ZipEntry zipEntry = zipFile.getEntry(getLastEntryName());
77+
try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry))) {
78+
blackhole.consume(ZipSampleFileStore.getString(inputStream));
79+
}
80+
}
81+
}
82+
83+
@Benchmark
84+
public static void readLastEntryByZipInputStream(SourceState sourceState, Blackhole blackhole) throws IOException {
85+
86+
try (
87+
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceState.compressedFile));
88+
ZipInputStream zipInputStream = new ZipInputStream(bis)
89+
) {
90+
ZipEntry entry;
91+
while ((entry = zipInputStream.getNextEntry()) != null) {
92+
if (Objects.equals(entry.getName(), getLastEntryName())){
93+
blackhole.consume(ZipSampleFileStore.getString(zipInputStream));
94+
}
95+
}
96+
}
97+
}
98+
99+
private static String getLastEntryName() {
100+
return String.format(ZipSampleFileStore.ENTRY_NAME_PATTERN, NUM_OF_FILES);
101+
}
102+
103+
public static void main(String[] args) throws Exception {
104+
Options options = new OptionsBuilder()
105+
.include(ZipBenchmark.class.getSimpleName()).threads(1)
106+
.shouldFailOnError(true)
107+
.shouldDoGC(true)
108+
.jvmArgs("-server").build();
109+
new Runner(options).run();
110+
}
111+
112+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.baeldung.zip;
2+
3+
import java.io.*;
4+
import java.nio.charset.Charset;
5+
import java.nio.charset.StandardCharsets;
6+
import java.util.*;
7+
import java.util.zip.ZipEntry;
8+
import java.util.zip.ZipOutputStream;
9+
10+
import org.apache.commons.io.IOUtils;
11+
12+
public class ZipSampleFileStore {
13+
14+
public static final String ENTRY_NAME_PATTERN = "str-data-%s.txt";
15+
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
16+
17+
private final File file;
18+
private final List<String> dataList;
19+
20+
public ZipSampleFileStore(int numOfFiles, int fileSize) throws IOException {
21+
22+
dataList = new ArrayList<>(numOfFiles);
23+
file = File.createTempFile("zip-sample", "");
24+
25+
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file))) {
26+
27+
for (int idx=0; idx<=numOfFiles; idx++) {
28+
29+
byte[] data = createRandomStringInByte(fileSize);
30+
dataList.add(new String(data, DEFAULT_ENCODING));
31+
32+
ZipEntry entry = new ZipEntry(String.format(ENTRY_NAME_PATTERN, idx));
33+
zos.putNextEntry(entry);
34+
zos.write(data);
35+
zos.closeEntry();
36+
}
37+
}
38+
}
39+
40+
public static byte[] createRandomStringInByte(int size) {
41+
Random random = new Random();
42+
byte[] data = new byte[size];
43+
for (int n = 0; n < data.length; n++) {
44+
char randomChar;
45+
int choice = random.nextInt(2); // 0 for uppercase, 1 for lowercase
46+
if (choice == 0) {
47+
randomChar = (char) ('A' + random.nextInt(26)); // 'A' to 'Z'
48+
} else {
49+
randomChar = (char) ('a' + random.nextInt(26)); // 'a' to 'z'
50+
}
51+
data[n] = (byte) randomChar;
52+
}
53+
return data;
54+
}
55+
56+
public File getFile() {
57+
return file;
58+
}
59+
60+
public List<String> getDataList() {
61+
return dataList;
62+
}
63+
64+
public static String getString(InputStream inputStream) throws IOException {
65+
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
66+
IOUtils.copy(inputStream, byteArrayOutputStream);
67+
return byteArrayOutputStream.toString(DEFAULT_ENCODING);
68+
}
69+
70+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.baeldung.zip;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.io.*;
6+
import java.util.*;
7+
import java.util.zip.*;
8+
9+
import org.junit.*;
10+
11+
public class ZipUnitTest {
12+
13+
private static File compressedFile;
14+
private static List<String> dataList = new ArrayList<>();
15+
16+
@BeforeClass
17+
public static void prepareData() throws IOException {
18+
ZipSampleFileStore sampleFileStore = new ZipSampleFileStore(ZipBenchmark.NUM_OF_FILES, ZipBenchmark.DATA_SIZE);
19+
compressedFile = sampleFileStore.getFile();
20+
dataList = sampleFileStore.getDataList();
21+
}
22+
23+
@Test
24+
public void whenCreateZipFile_thenCompressedSizeShouldBeLessThanOriginal() throws IOException {
25+
byte[] data = ZipSampleFileStore.createRandomStringInByte(10240);
26+
File file = File.createTempFile("zip-temp", "");
27+
28+
try (
29+
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
30+
ZipOutputStream zos = new ZipOutputStream(bos)
31+
) {
32+
ZipEntry zipEntry = new ZipEntry("zip-entry.txt");
33+
zos.putNextEntry(zipEntry);
34+
zos.write(data);
35+
zos.closeEntry();
36+
37+
assertThat(file.length()).isLessThan(data.length);
38+
}
39+
finally {
40+
file.delete();
41+
}
42+
}
43+
44+
@Test
45+
public void whenReadAllEntriesViaZipFile_thenDataIsEqualtoTheSource() throws IOException {
46+
47+
try (ZipFile zipFile = new ZipFile(compressedFile)) {
48+
Enumeration<? extends ZipEntry> entries = zipFile.entries();
49+
List<? extends ZipEntry> entryList = Collections.list(entries);
50+
51+
for (int idx=0; idx<entryList.size(); idx++) {
52+
ZipEntry zipEntry = entryList.get(idx);
53+
try (InputStream inputStream = zipFile.getInputStream(zipEntry)) {
54+
String actual = ZipSampleFileStore.getString(inputStream);
55+
assertThat(actual).as("Data for ZIP entry: " + zipEntry.getName()).isEqualTo(dataList.get(idx));
56+
}
57+
}
58+
}
59+
}
60+
61+
@Test
62+
public void whenReadAllEntriesViaZipInputStream_thenDataIsEqualtoTheSource() throws IOException {
63+
int idx = 0;
64+
try (
65+
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(compressedFile));
66+
ZipInputStream zipInputStream = new ZipInputStream(bis)
67+
) {
68+
ZipEntry zipEntry;
69+
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
70+
String actual = ZipSampleFileStore.getString(zipInputStream);
71+
assertThat(actual).as("Data for ZIP entry: " + zipEntry.getName()).isEqualTo(dataList.get(idx++));
72+
}
73+
}
74+
}
75+
76+
@AfterClass
77+
public static void cleanup() {
78+
if (compressedFile.exists()) {
79+
compressedFile.delete();
80+
}
81+
}
82+
83+
}

0 commit comments

Comments
 (0)