How to get exact size of zipped file before zippin

2019-09-02 04:37发布

I am using following standalone class to calculate size of zipped files before zipping. I am using 0 level compression, but still i am getting a difference of few bytes. Can you please help me out in this to get exact size?

Quick help will be appreciated.

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.FilenameUtils;


public class zipcode {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub



         try {
             CRC32 crc = new CRC32();

                byte[] b = new byte[1024]; 
                File file = new File("/Users/Lab/Desktop/ABC.xlsx");
            FileInputStream in = new FileInputStream(file);
            crc.reset();
                // out put file 
                ZipOutputStream out = new ZipOutputStream(new FileOutputStream("/Users/Lab/Desktop/ABC.zip"));


                // name the file inside the zip  file 

                ZipEntry entry = new ZipEntry("ABC.xlsx");
                entry.setMethod(ZipEntry.DEFLATED);
                entry.setCompressedSize(file.length());
                entry.setSize(file.length());
                entry.setCrc(crc.getValue());
                out.setMethod(ZipOutputStream.DEFLATED);
                out.setLevel(0);
                //entry.setCompressedSize(in.available());
                //entry.setSize(in.available());
                //entry.setCrc(crc.getValue());


                out.putNextEntry(entry); 
                // buffer size

                int count;

                while ((count = in.read(b)) > 0) {
                    System.out.println();
                    out.write(b, 0, count);
                }
                out.close();
                in.close();         
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

标签: java zip
1条回答
女痞
2楼-- · 2019-09-02 05:08

Firstly, I'm not convinced by explanation for why you need to do this. There is something wrong with your system design or implementation if it is necessary to know the file size before you start uploading.

Having said that, the solution is basically to create the ZIP file before you start uploading it:

  • Write the ZIP file to a temporary file and upload from that.

  • Write the ZIP file to an buffer in memory and upload from that.

  • If you don't have either the file space or the memory space, then:

    • Create "sink" outputStream that simply counts the bytes that are written to calculate the nominal file size.

    • Create / write the ZIP file to the sink, and capture the file size.

    • Open your connection for uploading.

    • Send the metadata including the file size.

    • Create / write the ZIP a second time, writing to the socket stream ... or whatever.

These 3 approaches will all allow you to create and send a compressed ZIP, if that is going to help.


If you insist on trying to do this on-the-fly in one pass, then you are going to need to read the ZIP file spec in forensic detail ... and do some messy arithmetic. Helping you is probably beyond the scope of a SO question.

查看更多
登录 后发表回答