I want to reset the ZipInputStream (ie back to the start position) in order to read certain files in order. How do I do that? I am so stucked...
ZipEntry entry;
ZipInputStream input = new ZipInputStream(fileStream);//item.getInputStream());
int check =0;
while(check!=2){
entry = input.getNextEntry();
if(entry.getName().toString().equals("newFile.csv")){
check =1;
InputStreamReader inputStreamReader = new InputStreamReader(input);
reader = new CSVReader(inputStreamReader);
//read files
//reset ZipInputStream if file is read.
}
reader.close();
}
if(entry.getName().toString().equals("anotherFile.csv")){
check =2;
InputStreamReader inputStreamReader = new InputStreamReader(input);
reader = new CSVReader(inputStreamReader);
//read files
//reset ZipInputStream if file is read.
}
reader.close();
}
}
ZipInputStream. close() method closes this input stream and releases any system resources associated with the stream.
The java. io. InputStream. reset() method repositions this stream to the position at the time the mark method was last called on this input stream.
ZipEntry getNextEntry() : Reads the next ZIP file entry and positions the stream at the beginning of the entry data. int read(byte[] b, int off, int len) : Reads from the current ZIP entry into an array of bytes.
If possible (i.e. you have an actual file, not just a stream to read from), try to use the ZipFile class rather than the more low-level ZipInputStream. ZipFile takes care of jumping around in the file and opening streams to individual entries.
ZipFile zip = new ZipFile(filename);
ZipEntry entry = zip.getEntry("newfile.csv");
if (entry != null){
CSVReader data = new CSVReader(new InputStreamReader(
zip.getInputStream(entry)));
}
Actually there is no way to reset a ZipInputStream
as you expect, because it does not support reset/markers etc.
But you can use an ByteArrayOutputStream
to buffer your InputStream
as byte[]
so you write a Class looking like
private byte[] readStreamBuffer;
private InputStream readStream;
public ZipClass(InputStream readStream){
this.readStream = readStream;
}
and a openReadStream
-method like this:
private ZipInputStream openReadStream(){
if (readStreamBuffer == null) {
//If there was no buffered data yet it will do some new
ByteArrayOutputStream readStreamBufferStream = new ByteArrayOutputStream();
try {
int read = 0;
byte[] buff = new byte[1024];
while ((read = zipFileInput.read(buff)) != -1) {
readStreamBufferStream.write(buff, 0, read);
}
readStreamBuffer = readStreamBufferStream.toByteArray();
}
finally {
readStreamBufferStream.flush();
readStreamBufferStream.close();
}
}
//Read from you new buffered stream data
readStream = new ByteArrayInputStream(readStreamBuffer);
//open new ZipInputStream
return new ZipInputStream(readStream);
}
Now you are able to read an entry and close it afterwards. If you call openReadStream
it will provide you a new ZipInputStream
, so you can selectively read Entries like this:
public InputStream read(String entry){
ZipInputStream unzipStream = openReadStream();
try {
return readZipEntry(unzipStream, entryName);
}
finally {
unzipStream.close(); //This closes the zipinputstream
}
}
calling the method readZipEntry
private InputStream readZipEntry(ZipInputStream zis, String entry) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
// get the zipped file list entry
try {
ZipEntry ze = zis.getNextEntry();
while (ze != null) {
if (!ze.isDirectory() && ze.getName().equals(entry)) {
int len;
byte[] buffer = new byte[BUFFER];
while ((len = zis.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
break;
}
ze = zis.getNextEntry();
}
}
finally {
zis.closeEntry();
}
InputStream is = new ByteArrayInputStream(out.toByteArray());
return is;
}
finally {
out.close();
}
}
And you will get out a new InputStream. You can now read multiple times from the same Input.
You can wrap the InputStream in a BufferedInputStream and call the methods mark() and reset(), like so:
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
bufferedInputStream.mark(100);
ZipInputStream zipInputStream = new ZipInputStream(bufferedInputStream);
any operation with zipInputStream ...
bufferedInputStream.reset();
The readLimit you pass to the mark method must be big enough to cover all the read operations you do with the inputStream. If you set it to the maximum supposed file size you can have in input you should be covered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With