9

I have byte[] zipFileAsByteArray

This zip file has rootDir --|
                            | --- Folder1 - first.txt
                            | --- Folder2 - second.txt  
                            | --- PictureFolder - image.png  

What I need is to get two txt files and read them, without saving any files on disk. Just do it in memory.

I tried something like this:

ByteArrayInputStream bis = new ByteArrayInputStream(processZip);
ZipInputStream zis = new ZipInputStream(bis);

Also I will need to have separate method go get picture. Something like this:

public byte[]image getImage(byte[] zipContent);

Can someone help me with idea or good example how to do that ?

ManoDestra
  • 6,047
  • 6
  • 24
  • 50
TNN
  • 406
  • 2
  • 6
  • 14
  • I think that what you are looking for can be found at: http://stackoverflow.com/questions/15667125/read-content-from-files-which-are-inside-zip-file. For what it concerns the image, you should be able to do that looking at the following: http://www.mkyong.com/java/how-to-convert-byte-to-bufferedimage-in-java/. In order to detect whether to call the getImage method, do check the extension of the file. – LoreV Apr 11 '16 at 13:00

2 Answers2

8

Here is an example:

public static void main(String[] args) throws IOException {
    ZipFile zip = new ZipFile("C:\\Users\\mofh\\Desktop\\test.zip");


    for (Enumeration e = zip.entries(); e.hasMoreElements(); ) {
        ZipEntry entry = (ZipEntry) e.nextElement();
        if (!entry.isDirectory()) {
            if (FilenameUtils.getExtension(entry.getName()).equals("png")) {
                byte[] image = getImage(zip.getInputStream(entry));
                //do your thing
            } else if (FilenameUtils.getExtension(entry.getName()).equals("txt")) {
                StringBuilder out = getTxtFiles(zip.getInputStream(entry));
                //do your thing
            }
        }
    }


}

private  static StringBuilder getTxtFiles(InputStream in)  {
    StringBuilder out = new StringBuilder();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String line;
    try {
        while ((line = reader.readLine()) != null) {
            out.append(line);
        }
    } catch (IOException e) {
        // do something, probably not a text file
        e.printStackTrace();
    }
    return out;
}

private static byte[] getImage(InputStream in)  {
    try {
        BufferedImage image = ImageIO.read(in); //just checking if the InputStream belongs in fact to an image
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        return baos.toByteArray();
    } catch (IOException e) {
        // do something, it is not a image
        e.printStackTrace();
    }
    return null;
}

Keep in mind though I am checking a string to diferentiate the possible types and this is error prone. Nothing stops me from sending another type of file with an expected extension.

dambros
  • 4,052
  • 1
  • 20
  • 37
  • I don't have ZipFile zip = new ZipFile("C:\\Users\\mofh\\Desktop\\test.zip"); my entry is ZipInputStream zis = new ZipInputStream(bis); – TNN Apr 11 '16 at 13:41
  • Simply use it then... If you have the byte[] for the zip, just `ZipFile zip = new ZipInputStream(new ByteArrayInputStream(processZip))`. – dambros Apr 11 '16 at 13:46
  • @dambros much better will be using try with resources for zip file: `try (ZipFile zip = ...) {` – catch23 Aug 17 '20 at 10:45
2

You can do something like:

public static void main(String args[]) throws Exception
{
    //bis, zis as you have
    try{
        ZipEntry file;
        while((file = zis.getNextEntry())!=null) // get next file and continue only if file is not null
        {
            byte b[] = new byte[(int)file.getSize()]; // create array to read.
            zis.read(b); // read bytes in b
            if(file.getName().endsWith(".txt")){
                // read files. You have data in `b`
            }else if(file.getName().endsWith(".png")){
                // process image
            }
        }
    }
    finally{
        zis.close();
    }
}
dryairship
  • 5,842
  • 2
  • 29
  • 53