Unzipping a file from InputStream and returning another InputStream
I am trying to write a function which will accept an InputStream
with zipped file data and would return another InputStream
with unzipped data.
The zipped file will only contain a single file and thus there 开发者_开发百科is no requirement of creating directories, etc...
I tried looking at ZipInputStream
and others but I am confused by so many different types of streams in Java.
Concepts
GZIPInputStream is for streams (or files) zipped as gzip (".gz" extension). It doesn't have any header information.
This class implements a stream filter for reading compressed data in the GZIP file format
If you have a real zip file, you have to use ZipFile to open the file, ask for the list of files (one in your example) and ask for the decompressed input stream.
Your method, if you have the file, would be something like:
// ITS PSEUDOCODE!!
private InputStream extractOnlyFile(String path) {
ZipFile zf = new ZipFile(path);
Enumeration e = zf.entries();
ZipEntry entry = (ZipEntry) e.nextElement(); // your only file
return zf.getInputStream(entry);
}
Reading an InputStream with the content of a .zip file
Ok, if you have an InputStream you can use (as @cletus says) ZipInputStream. It reads a stream including header data.
ZipInputStream is for a stream with [header information + zippeddata]
Important: if you have the file in your PC you can use ZipFile
class to access it randomly
This is a sample of reading a zip-file through an InputStream:
import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Main {
public static void main(String[] args) throws Exception
{
FileInputStream fis = new FileInputStream("c:/inas400.zip");
// this is where you start, with an InputStream containing the bytes from the zip file
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry entry;
// while there are entries I process them
while ((entry = zis.getNextEntry()) != null)
{
System.out.println("entry: " + entry.getName() + ", " + entry.getSize());
// consume all the data from this entry
while (zis.available() > 0)
zis.read();
// I could close the entry, but getNextEntry does it automatically
// zis.closeEntry()
}
}
}
If you can change the input data I would suggested you to use GZIPInputStream
.
GZipInputStream
is different from ZipInputStream
since you only have one data inside it. So the whole input stream represents the whole file. In ZipInputStream
the whole stream contains also the structure of the file(s) inside it, which can be many.
It is on scala syntax:
def unzipByteArray(input: Array[Byte]): String = {
val zipInputStream = new ZipInputStream(new ByteArrayInputStream(input))
val entry = zipInputStream.getNextEntry
IOUtils.toString(zipInputStream, StandardCharsets.UTF_8)
}
Unless I'm missing something, you should absolutely try and get ZipInputStream
to work and there's no reason it shouldn't (I've certainly used it on several occasions).
What you should do is try and get ZipInputStream
to work and if you can't, post the code and we'll help you with whatever problems you're having.
Whatever you do though, don't try and reinvent its functionality.
精彩评论