Example of Java file compression and decompression [zip format gzip format]

  • 2020-05-27 05:35:21
  • OfStack

Java realizes the decompression and compression functions of ZIP basically by using the polypeptide and recursive technology of Java, which can compress and decompress a single file and any cascade folder, which is a good example for some beginners.

zip plays the roles of archiving and compression; gzip does not archive files, just compress a single file, so on the UNIX platform, the command tar is usually used to create a single file and then gzip to compress the file.

The Java I/O library also includes classes that can read and write streams in a compressed format. To provide compression capabilities, simply wrap them around the existing I/O classes. These classes are not Reader and Writer, but subclasses of InputStream and OutStreamput. This is because the compression algorithm is for byte rather than characters.
Related classes and interfaces:

Checksum interface: the interface implemented by the Adler32 and CRC32 classes

Adler32: the Alder32 algorithm is used to calculate the number of Checksum

CRC32: the CRC32 algorithm is used to calculate the number of Checksum

CheckedInputStream: a derived class of InputStream that gets a checksum of the input stream and Checksum to verify the integrity of the data

CheckedOutputStream: a derived class of OutputStream that gets checkouts for the output stream and Checksum to verify data integrity

DeflaterOutputStream: the base class of the compressed class.

ZipOutputStream: a subclass of DeflaterOutputStream that compresses data into Zip file format.

GZIPOutputStream: a subclass of DeflaterOutputStream that compresses data into the GZip file format

InflaterInputStream: extract the base class of the class

ZipInputStream: a subclass of InflaterInputStream that can extract data in the Zip format

GZIPInputStream: a subclass of InflaterInputStream that decompresses data in Zip format

Class ZipEntry: represents the ZIP file entry

ZipFile class: this class is used to read entries from ZIP files

Use ZIP to compress and uncompress multiple files

Java has comprehensive support for the Zip format class library, which allows you to compress multiple files into a single zip. This library USES the standard Zip format, so it is compatible with many compression tools.

The ZipOutputStream class sets the compression method and the compression level to be used in the compression mode, and zipOutputStream.setMethod (int method) sets the default compression method for entries. As long as no compression method is specified for a single ZIP file entry, the compression method set by ZipOutputStream is used for storage, with a default value of ZipOutputStream.DEFLATED (for compressed storage) and can also be set to STORED (for packaged archive storage only). After setting the compression method ZipOutputStream as DEFLATED, we can further use the setLevel(int level) method to set the compression level. The compression level value is 0 to 9 (the higher the value, the more powerful the compression), and the default is Deflater.DEFAULT_COMPRESSION =-1. Of course, we can also set the compression method for a single condition through the setMethod method of item ZipEntry.

Class ZipEntry describes a compressed file stored in an ZIP file. The ZIP class contains a number of methods that you can use to set up and get information about the ZIP entry. Class ZipEntry is used by ZipFile[zipFile.getInputStream (ZipEntry entry)] and ZipInputStream to read ZIP files and ZipOutputStream to write ZIP files. Here are some useful ways to do this: getName() returns the entry name, isDirectory() returns true (defined as the entry whose name ends with '/') if it is a directory entry, setMethod(int method) sets the compression method for the entry, which can be ZipOutputStream.STORED or ZipOutputStream.DEFLATED.

In the following example, we used apache's zip toolkit (ant.jar), because the built-in java does not support the Chinese path. However, they used the same way, except that the apache compression tool had more interfaces to set the encoding mode, while the others were basically the same. . In addition, if you use org apache. tools. zip. ZipOutputStream to compression, we can only use org. apache. tools. zip. ZipEntry to extract, and cannot use java. util. zip. ZipInputStream to extract the read, of course apache did not provide ZipInputStream class.

File compression:


package gizAction;
import java.io.*;
import java.util.zip.*;
/**
 * @author Dana ・ Li
 * <p>
 *  The program implements ZIP The compression [compression]
 * <p>
 *  General functions include polymorphic, recursive and so on JAVA Core technology, can be a single file and any cascade folder compression and decompression.   You need to customize the source input path and the target output path in your code. 
 * <p>
 *  In this code, you implement the compression part 
 */
public class ZipCompressing {
 private int k = 1; //  Define the recursion frequency variable 

 private void zip(String zipFileName, File inputFile) throws Exception {
  System.out.println(" In the compression ...");
  ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
  BufferedOutputStream bo = new BufferedOutputStream(out);
  zip(out, inputFile, inputFile.getName(), bo);
  bo.close();
  out.close(); //  Output stream shutdown 
  System.out.println(" compressing ");
 }
 private void zip(ZipOutputStream out, File f, String base,
   BufferedOutputStream bo) throws Exception { //  Method overloading 
  if (f.isDirectory()){
   File[] fl = f.listFiles();
   if (fl.length == 0){
    out.putNextEntry(new ZipEntry(base + "/")); //  create zip Compression entry point base
    System.out.println(base + "/");
   }
   for (int i = 0; i < fl.length; i++) {
    zip(out, fl[i], base + "/" + fl[i].getName(), bo); //  Recursively traversing subfolders 
   }
   System.out.println(" The first " + k + " A recursive ");
   k++;
  } else {
   out.putNextEntry(new ZipEntry(base)); //  create zip Compression entry point base
   System.out.println(base);
   FileInputStream in = new FileInputStream(f);
   BufferedInputStream bi = new BufferedInputStream(in);
   int b;
   while ((b = bi.read()) != -1) {
    bo.write(b); //  Writes the byte stream to the current zip directory 
   }
   bi.close();
   in.close(); //  Input stream shutdown 
  }
 }
 /**
  *  test 
  * @param args
  */
 public static void main(String[] args) {
  ZipCompressing book = new ZipCompressing();
  try {
   book.zip("F:\\ziptest.zip",new File("F:\\ziptest"));
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

File unzip:


package gizAction;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
 * @author Dana ・ Li
 * <p>
 *  The program implements ZIP Unpack the [decompression]
 * <p>
 *  General functions include polymorphic, recursive and so on JAVA Core technology, can be a single file and any cascade folder compression and decompression.   You need to customize the source input path and the target output path in your code. 
 * <p>
 *  In this code, the implementation is the decompression part; 
 */ 
public class zipDecompressing { 

 public static void main(String[] args) { 
  // TODO Auto-generated method stub 
  long startTime=System.currentTimeMillis(); 
  try { 
   ZipInputStream Zin=new ZipInputStream(new FileInputStream( 
     "F:\\ziptest.zip"));// The input source zip The path  
   BufferedInputStream Bin=new BufferedInputStream(Zin); 
   String Parent="F:\\ziptest\\"; // Output path (folder directory)  
   File Fout=null; 
   ZipEntry entry; 
   try { 
    while((entry = Zin.getNextEntry())!=null && !entry.isDirectory()){ 
     Fout=new File(Parent,entry.getName()); 
     if(!Fout.exists()){ 
      (new File(Fout.getParent())).mkdirs(); 
     } 
     FileOutputStream out=new FileOutputStream(Fout); 
     BufferedOutputStream Bout=new BufferedOutputStream(out); 
     int b; 
     while((b=Bin.read())!=-1){ 
      Bout.write(b); 
     } 
     Bout.close(); 
     out.close(); 
     System.out.println(Fout+" Unpack the success ");  
    } 
    Bin.close(); 
    Zin.close(); 
   } catch (IOException e) { 
    e.printStackTrace(); 
   } 
  } catch (FileNotFoundException e) { 
   e.printStackTrace(); 
  } 
  long endTime=System.currentTimeMillis(); 
  System.out.println(" Time consuming:  "+(endTime-startTime)+" ms"); 
 } 

}

Single file compression using GZIP

GZIP's interface is relatively simple, so you can use it if you only need to compress one stream. Of course, it can compress the character stream, and can compress the byte stream. Here is a text file compressed in GBK encoding format.

The use of compressed classes is very simple; Simply wrap the output stream in GZIPOutputStream or ZipOutputStream, and the input stream in GZIPInputStream or ZipInputStream. The rest are normal I/O operations.


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GZIPcompress {
 public static void main(String[] args) throws IOException {
  // Prepare for compression 1 Character file, note, the character file here if GBK coded 
  BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(
    "e:/tmp/source.txt"), "GBK"));
  // use GZIPOutputStream packaging OutputStream The stream, making it specific to the compression properties, will eventually be generated test.txt.gz Compressed package 
  // And it has 1 called test.txt The file 
  BufferedOutputStream out = new BufferedOutputStream(new GZIPOutputStream(
    new FileOutputStream("test.txt.gz")));
  System.out.println(" Start writing compressed files ...");
  int c;
  while ((c = in.read()) != -1) {

   /* 
    *  Note, this is compression 1 Character file, the front is a character stream to read, can not be stored directly c Because the c is Unicode
    *  Code, this will lose the information (of course, the encoding format itself is wrong), so here to GBK I'll solve it and then I'll put it in. 
    */
   out.write(String.valueOf((char) c).getBytes("GBK"));
  }
  in.close();
  out.close();
  System.out.println(" Start reading the zip file ...");
  // use GZIPInputStream packaging InputStream Flow, so that it has decompression characteristics 
  BufferedReader in2 = new BufferedReader(new InputStreamReader(
    new GZIPInputStream(new FileInputStream("test.txt.gz")), "GBK"));
  String s;
  // Read the contents of a compressed file 
  while ((s = in2.readLine()) != null) {
   System.out.println(s);
  }
  in2.close();
 }
}


Related articles: