0
# Stream Compression
1
2
Standard Java I/O streams for transparent compression and decompression. ZstdInputStream and ZstdOutputStream integrate seamlessly with existing Java I/O patterns and are fully compatible with the standard zstd command-line tool.
3
4
## Capabilities
5
6
### ZstdInputStream - Decompression Stream
7
8
Transparent decompression of Zstd-compressed data through standard InputStream interface.
9
10
```java { .api }
11
/**
12
* Creates a decompressing InputStream that reads compressed data from underlying stream
13
* @param inStream underlying InputStream containing compressed data
14
* @throws IOException if initialization fails
15
*/
16
public ZstdInputStream(InputStream inStream) throws IOException;
17
18
/**
19
* Sets continuous mode for handling unfinished frames
20
* @param b true to enable continuous mode (don't fail on unfinished frames)
21
* @return this instance for method chaining
22
*/
23
public ZstdInputStream setContinuous(boolean b);
24
25
/**
26
* Gets current continuous mode setting
27
* @return true if continuous mode is enabled
28
*/
29
public boolean getContinuous();
30
31
/**
32
* Reads decompressed data into buffer
33
* @param dst destination buffer
34
* @param offset offset in destination buffer
35
* @param len maximum number of bytes to read
36
* @return number of bytes read, or -1 if end of stream
37
* @throws IOException if decompression fails
38
*/
39
public int read(byte[] dst, int offset, int len) throws IOException;
40
41
/**
42
* Reads a single decompressed byte
43
* @return byte value (0-255) or -1 if end of stream
44
* @throws IOException if decompression fails
45
*/
46
public int read() throws IOException;
47
48
/**
49
* Returns estimate of bytes available for reading without blocking
50
* @return estimated available bytes
51
* @throws IOException if stream is closed
52
*/
53
public int available() throws IOException;
54
55
/**
56
* Mark/reset not supported
57
* @return false (mark/reset not supported)
58
*/
59
public boolean markSupported();
60
61
/**
62
* Skips bytes in the decompressed stream
63
* @param toSkip number of bytes to skip
64
* @return actual number of bytes skipped
65
* @throws IOException if decompression fails
66
*/
67
public long skip(long toSkip) throws IOException;
68
69
/**
70
* Closes the stream and underlying InputStream
71
* @throws IOException if close fails
72
*/
73
public void close() throws IOException;
74
```
75
76
**Usage Examples:**
77
78
```java
79
import com.github.luben.zstd.ZstdInputStream;
80
import java.io.*;
81
82
// Decompress a file
83
try (FileInputStream fis = new FileInputStream("data.zst");
84
ZstdInputStream zis = new ZstdInputStream(fis);
85
FileOutputStream fos = new FileOutputStream("data.txt")) {
86
87
byte[] buffer = new byte[8192];
88
int bytesRead;
89
while ((bytesRead = zis.read(buffer)) != -1) {
90
fos.write(buffer, 0, bytesRead);
91
}
92
}
93
94
// Decompress from byte array
95
byte[] compressedData = ...; // compressed data
96
try (ByteArrayInputStream bais = new ByteArrayInputStream(compressedData);
97
ZstdInputStream zis = new ZstdInputStream(bais)) {
98
99
// Read decompressed data
100
byte[] buffer = new byte[1024];
101
int bytesRead = zis.read(buffer);
102
String result = new String(buffer, 0, bytesRead);
103
}
104
105
// Continuous mode for streaming/incomplete data
106
try (ZstdInputStream zis = new ZstdInputStream(inputStream).setContinuous(true)) {
107
// Will not fail on unfinished frames - useful for live streaming
108
byte[] buffer = new byte[1024];
109
int bytesRead = zis.read(buffer);
110
}
111
```
112
113
### ZstdOutputStream - Compression Stream
114
115
Transparent compression of data through standard OutputStream interface.
116
117
```java { .api }
118
/**
119
* Creates a compressing OutputStream with default settings
120
* @param outStream underlying OutputStream for compressed data
121
* @throws IOException if initialization fails
122
*/
123
public ZstdOutputStream(OutputStream outStream) throws IOException;
124
125
/**
126
* Creates a compressing OutputStream with specified compression level
127
* @param outStream underlying OutputStream for compressed data
128
* @param level compression level (1-22, higher = better compression)
129
* @throws IOException if initialization fails
130
*/
131
public ZstdOutputStream(OutputStream outStream, int level) throws IOException;
132
133
/**
134
* Creates a compressing OutputStream with full control
135
* @param outStream underlying OutputStream for compressed data
136
* @param level compression level (1-22, higher = better compression)
137
* @param closeFrameOnFlush true to close frame on flush (enables frame-by-frame processing)
138
* @throws IOException if initialization fails
139
*/
140
public ZstdOutputStream(OutputStream outStream, int level, boolean closeFrameOnFlush) throws IOException;
141
142
/**
143
* Writes data to be compressed
144
* @param src source data buffer
145
* @param offset offset in source buffer
146
* @param len number of bytes to write
147
* @throws IOException if compression fails
148
*/
149
public void write(byte[] src, int offset, int len) throws IOException;
150
151
/**
152
* Writes a single byte to be compressed
153
* @param i byte value to write
154
* @throws IOException if compression fails
155
*/
156
public void write(int i) throws IOException;
157
158
/**
159
* Flushes compressed data to underlying stream
160
* @throws IOException if flush fails
161
*/
162
public void flush() throws IOException;
163
164
/**
165
* Closes the stream and finishes compression
166
* @throws IOException if close fails
167
*/
168
public void close() throws IOException;
169
```
170
171
**Usage Examples:**
172
173
```java
174
import com.github.luben.zstd.ZstdOutputStream;
175
import java.io.*;
176
177
// Compress a file
178
try (FileInputStream fis = new FileInputStream("data.txt");
179
FileOutputStream fos = new FileOutputStream("data.zst");
180
ZstdOutputStream zos = new ZstdOutputStream(fos, 6)) {
181
182
byte[] buffer = new byte[8192];
183
int bytesRead;
184
while ((bytesRead = fis.read(buffer)) != -1) {
185
zos.write(buffer, 0, bytesRead);
186
}
187
}
188
189
// Compress to byte array
190
ByteArrayOutputStream baos = new ByteArrayOutputStream();
191
try (ZstdOutputStream zos = new ZstdOutputStream(baos, 10)) {
192
String data = "Data to compress";
193
zos.write(data.getBytes());
194
}
195
byte[] compressedData = baos.toByteArray();
196
197
// Frame-by-frame compression for streaming
198
try (ZstdOutputStream zos = new ZstdOutputStream(outputStream, 6, true)) {
199
// Each flush creates a complete frame
200
zos.write("First chunk".getBytes());
201
zos.flush(); // Creates first frame
202
203
zos.write("Second chunk".getBytes());
204
zos.flush(); // Creates second frame
205
}
206
```
207
208
### Stream Integration Patterns
209
210
Common patterns for integrating with Java I/O.
211
212
**Buffered I/O:**
213
214
```java
215
// Wrap with BufferedStreams for better performance
216
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.zst"));
217
ZstdInputStream zis = new ZstdInputStream(bis);
218
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
219
220
byte[] buffer = new byte[8192];
221
int bytesRead;
222
while ((bytesRead = zis.read(buffer)) != -1) {
223
bos.write(buffer, 0, bytesRead);
224
}
225
}
226
```
227
228
**Try-with-resources:**
229
230
```java
231
// Automatic resource management
232
try (InputStream is = Files.newInputStream(Paths.get("input.zst"));
233
ZstdInputStream zis = new ZstdInputStream(is);
234
Reader reader = new InputStreamReader(zis, StandardCharsets.UTF_8);
235
BufferedReader br = new BufferedReader(reader)) {
236
237
return br.lines().collect(Collectors.toList());
238
}
239
```
240
241
**Chain with other streams:**
242
243
```java
244
// Decompress -> decrypt -> parse
245
try (ZstdInputStream zis = new ZstdInputStream(encryptedInputStream);
246
CipherInputStream cis = new CipherInputStream(zis, cipher);
247
ObjectInputStream ois = new ObjectInputStream(cis)) {
248
249
return (MyObject) ois.readObject();
250
}
251
```
252
253
## Performance Considerations
254
255
- **Buffer sizes**: Use appropriately sized buffers (8KB-64KB) for optimal performance
256
- **Compression levels**: Balance between speed (1-3) and compression ratio (10+)
257
- **Frame mode**: Use `closeFrameOnFlush=true` for streaming applications where frames need to be self-contained
258
- **Continuous mode**: Enable for applications handling incomplete or streaming data
259
- **Buffered I/O**: Wrap streams with BufferedInputStream/BufferedOutputStream for better throughput
260
261
## Error Handling
262
263
Stream operations throw IOException on errors. The underlying Zstd error information is included in the exception message:
264
265
```java
266
try (ZstdInputStream zis = new ZstdInputStream(inputStream)) {
267
// Stream operations
268
} catch (IOException e) {
269
// e.getMessage() contains Zstd error details if compression/decompression failed
270
System.err.println("Compression error: " + e.getMessage());
271
}
272
```