Syntax highlighter header

Saturday, 12 September 2020

Faster way of creating ZIP file

Zip file is normally used for distributing files and directories.  Zip file serves two purposes one is compressing the file and another of creating a achive of multiple files and directories. Now a days with faster internet speed and precompressed files like jpg and mp4 etc. It will be faster to disable compression altogether to speed up the compression. I wrote a simple program in java to create zip file without compression. I was using a mp4 file as content of zip file. With compression enabled it was taking 5 time more time and giving a compression of 5% which is not worth for time spent. Following is the source code:


package zipperformance;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.util.zip.CRC32;

public class ZipCreater {
	public static void main(String[] args) {
		
		long startTime = System.currentTimeMillis();
		zipDirectory("files", "test.zip");
		long endTime = System.currentTimeMillis();
		
		System.out.println(endTime-startTime);
		
		
	}
	
    public static void zipDirectory( String dirPath, String zipFilePath )
    {

        FileOutputStream fos = null;
        try
        {
            // Create the file output streams for both the file and the zip.

            File file = new File( zipFilePath );
            if(file.getParentFile()!=null) {
            	file.getParentFile().mkdirs();
            }
            fos = new FileOutputStream( zipFilePath );
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            ZipOutputStream zos = new ZipOutputStream( fos );
            zos.setLevel(Deflater.BEST_SPEED);
            dirFunc( dirPath, dirPath, zos );

            // Close the file output streams for both the file and the zip.
            zos.flush();
            zos.close();
            fos.close();
        }
        catch ( IOException e )
        {
        	e.printStackTrace();
        }
    }
    
    private static void dirFunc( String dirName, String baseExportPath, ZipOutputStream zos )
    {
        try
        {
            File dirObj = new File( dirName );
            if ( dirObj.exists() == true )
            {
                if ( dirObj.isDirectory() == true )
                {
                    // Create an array of File objects, one for each file or directory in dirObj.
                    File[] fileList = dirObj.listFiles();
                    // Loop through File array and display.
                    for ( int i = 0; i < fileList.length; i++ )
                    {
                        if ( fileList[i].isDirectory() )
                        {
                            dirFunc( fileList[i].getPath(), baseExportPath, zos );
                        }
                        else if ( fileList[i].isFile() )

                        {
                            // Call the zipFunc function
                            zipFunc( fileList[i].getPath(), baseExportPath, zos );
                        }
                    }
                }
            }
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }

    private static void zipFunc( String filePath, String baseExportPath, ZipOutputStream zos )
    {
        try
        {
            String absolutePath = filePath;
            String prefixFilePath = baseExportPath;

            int index = prefixFilePath.length();

            filePath = filePath.substring( ++index );

            // Create a file input stream and a buffered input stream.
            long size = Files.size(Paths.get(absolutePath));
            FileInputStream fis = new FileInputStream( absolutePath );
            BufferedInputStream bis = new BufferedInputStream( fis );
            CRC32 crc32 = new CRC32();
            byte[] data = new byte[1024*128];
            int byteCount;

            // Create a loop that reads from the buffered input stream and writes
            // to the zip output stream until the bis has been entirely read.
            while ( ( byteCount = bis.read( data, 0, data.length ) ) > -1 )
            {
                crc32.update( data, 0, byteCount );
            }
            long crc=crc32.getValue();

            // Create a Zip Entry and put it into the archive (no data yet).
            ZipEntry fileEntry = new ZipEntry( filePath );
            fileEntry.setMethod(ZipEntry.STORED);
            fileEntry.setSize(size);
            fileEntry.setCrc(crc);
            zos.putNextEntry( fileEntry );

            bis.close();
            fis = new FileInputStream( absolutePath );
            bis = new BufferedInputStream( fis );
            
            // Create a loop that reads from the buffered input stream and writes
            // to the zip output stream until the bis has been entirely read.
            while ( ( byteCount = bis.read( data, 0, data.length ) ) > -1 )
            {
                zos.write( data, 0, byteCount );
            }
        }
        catch ( IOException e )
        {
        	e.printStackTrace();
        }
    }
}


No comments:

Post a Comment