Read Zip file content without extracting in java
Asked Answered
M

3

11

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 ?

May answered 11/4, 2016 at 12:30 Comment(1)
I think that what you are looking for can be found at: #15667625. For what it concerns the image, you should be able to do that looking at the following: 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.Marianomaribel
B
12

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.

Blondellblondelle answered 11/4, 2016 at 13:18 Comment(4)
I don't have ZipFile zip = new ZipFile("C:\\Users\\mofh\\Desktop\\test.zip"); my entry is ZipInputStream zis = new ZipInputStream(bis);May
Simply use it then... If you have the byte[] for the zip, just ZipFile zip = new ZipInputStream(new ByteArrayInputStream(processZip)).Blondellblondelle
@Blondellblondelle much better will be using try with resources for zip file: try (ZipFile zip = ...) {Silas
@dambros, how can you instantiate a new ZipInputStream as a ZipFile? I get a compile error...Branham
C
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();
    }
}
Cazzie answered 11/4, 2016 at 13:18 Comment(1)
file.getSize() return -1 ;May
G
-1

You can use below code.
But need to make sure that you S3 Bucket initial setup.

import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.ResponseHeaderOverrides;
import com.amazonaws.services.s3.model.S3Object;

import java.io.*;

import static com.amazonaws.regions.Regions.US_EAST_1;

public class GetObject2 {

    public static void main(String[] args) throws IOException {

        String bucketName = "Give Yout Bucket Name";
        String key = "Give your String Key";


        S3Object fullObject = null, objectPortion = null, headerOverrideObject = null;
        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(US_EAST_1)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();


            // Get an object and print its contents.
            System.out.println("Downloading an object");
            fullObject = s3Client.getObject(new GetObjectRequest(bucketName, key));
            System.out.println("Content-Type: " + fullObject.getObjectMetadata().getContentType());
            System.out.println("Content: ");
            displayTextInputStream(fullObject.getObjectContent());

            File localFile = new File("C:\\awstest.zip");
            ObjectMetadata object = s3Client.getObject(new GetObjectRequest(bucketName, key), localFile);

            // Get a range of bytes from an object and print the bytes.
            GetObjectRequest rangeObjectRequest = new GetObjectRequest(bucketName, key)
                    .withRange(0, 9);
            objectPortion = s3Client.getObject(rangeObjectRequest);
            System.out.println("Printing bytes retrieved.");
            displayTextInputStream(objectPortion.getObjectContent());

            // Get an entire object, overriding the specified response headers, and print the object's content.
            ResponseHeaderOverrides headerOverrides = new ResponseHeaderOverrides()
                    .withCacheControl("No-cache")
                    .withContentDisposition("attachment; filename=example.txt");
            GetObjectRequest getObjectRequestHeaderOverride = new GetObjectRequest(bucketName, key)
                    .withResponseHeaders(headerOverrides);
            headerOverrideObject = s3Client.getObject(getObjectRequestHeaderOverride);
            displayTextInputStream(headerOverrideObject.getObjectContent());
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        } finally {
            // To ensure that the network connection doesn't remain open, close any open input streams.
            if (fullObject != null) {
                fullObject.close();
            }
            if (objectPortion != null) {
                objectPortion.close();
            }
            if (headerOverrideObject != null) {
                headerOverrideObject.close();
            }
        }
    }

    static void displayTextInputStream(InputStream input) throws IOException {
        // Read the text input stream one line at a time and display each line.
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        String line = null;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        System.out.println();
    }
}
Groundless answered 6/8, 2022 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.