APP File/directory compression using Gnu ZIP

Joe

Thành viên VIP
21/1/13
2,927
1,314
113
Hi
Tools such as RAR and ZIP are too common to everyone. The tools are usually free. The question is what Compression tool is the best? WinRAR? ZIP? If you google and search for the comparison between RAR and ZIP you'd find a page-long link-list to the comparing results. Because RAR is a newer development it is therefore more efficient than ZIP.
But no one thinks about the most-efficient Compression technique GZIP (Gnu ZIP) which is, alas, just an API and if you want to use it you have to build yourself a tool (or app) that bases on this GZIP API. I have showed you HERE how to build a ZIP app and a GZIP app. Today I show you how to merge both tools into ONE called JZIP in JavaFX. The following Screenshots show you how efficient GZIP in comparison with ZIP and RAR (by the same content of 3 big files) is.

JZIP_0.jpg

JZIP.jpg

GZIP is much better than WinRAR and ZIP.

How to create the JZIP tool:
  1. Download the jzip.zip and unzip it to a directory (e.j C:/myJZIP)
  2. run "javac -g:none -d ./classes JZIP.java" on a console with the home directory mentioned in 1)
  3. move to directory classes with "cd classes"
  4. run "jar -cvfm ../jzip.jar JMANIFEST.MF JZIP.class css.css zip.jpg > ../o.txt"
  5. return to home directory (C:/myJZIP)
  6. run "javaw -jar -Xms512M jzip.jar" and see how it works....
Joe
 

Attachments

Sửa lần cuối:

Joe

Thành viên VIP
21/1/13
2,927
1,314
113
To generalize the ZIP/GZIP technique I have developed TWO Java APIs
  1. JZIPInputStream
  2. JZIPOutputStream
so that you can build your own Compression tool in SWING (or JavaFX) that bases on the mentioned APIs. The previous JZIP app is modified and now runs with the 2 new APIs. The app can now recognize the file type (i.e. ZIPPED or GZIPPED content) and process it accordingly to additional requirements (e.g. add, remove or replace files).

The coding is simple. Example:

The old way (JZIP.java)
Java:
        if (fMode) { // ZIP mode
          int cnt = 0;
          ZipOutputStream zos = null;
          if (ow) { // Overwrite or new zip file
            zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(to, false)));
            txtA.appendText("Following file"+(zips.size() > 1? "s are":"is")+" zipped to: "+to+"\n");
            for (int le, i = 0, mx = zips.size(); i < mx; ++i) {
              String s = zips.get(i);
              if (!to.equals(s)) {
                zos.putNextEntry(new ZipEntry(entryName(s)));
                byte[] bb = Files.readAllBytes((new File(s)).toPath());
                txtA.appendText("Zipped: "+s+"\n");
                zos.write(bb);
                zos.flush();
                ++cnt;
              }
            }
            txtA.appendText("Done! "+cnt+" file"+(cnt > 1?"s are":" is")+" zipped\n\n");
          } else { // Append/Replace
            int app = 0;
            byte[] bb = Files.readAllBytes((new File(to)).toPath());
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            bao.write(bb);
            // overwrite the old ZIP and append it with new entries
            zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(to, false)));
            ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(bao.toByteArray()));

            int mx = zips.size();
            int rp[] = new int[mx];
            out: while (true) {
              ZipEntry ze = zis.getNextEntry();
              if (ze == null) { // last entry
                zis.closeEntry();
                zis.close();
                break;
              }
              int i;
              String n = ze.getName();
              for (i = 0; i < mx; ++i) {
                String s = zips.get(i);
                if (entryName(s).equals(n)) {
                  rp[i] = 1; // replaced
                  continue out;
                }
              }
              zos.putNextEntry(new ZipEntry(n));
              while ((i = zis.read(bb)) > 0) zos.write(bb, 0, i);
              zos.flush();
              ++cnt;
            }
            int rep = 0;
            for (int le, i = 0; i < mx; ++i) {
              String s = zips.get(i);
              if (!to.equals(s)) {
                zos.putNextEntry(new ZipEntry(entryName(s)));
                if (rp[i] > 0) {
                  ++rep;
                  txtA.appendText("Replaced: "+s+"\n");
                } else  txtA.appendText("Appended "+s+"\n");
                bb = Files.readAllBytes((new File(s)).toPath());
                zos.write(bb);
                zos.flush();
                ++cnt;
                ++app;
              }
            }
            txtA.appendText("Done! "+app+" file");
            if (app > 1) txtA.appendText("s are ");
            else txtA.appendText(" is ");
            if (rep == app) txtA.appendText("replaced");
            else if (rep == 0) txtA.appendText("appended");
            else txtA.appendText("appended or replaced");
            txtA.appendText(". Total zipped Files: "+cnt+"\n\n");
          }
          if (zos != null) {
            zos.closeEntry();
            zos.flush();
            zos.close();
          }
        } else { // GZIP mode
          int cnt = 0;
          load = !JZIP.equals(to);
          GZIPOutputStream zos = null;
          if (ow) { // Overwrite or new zip file
            zos = new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(to, false)));
            txtA.appendText("Following file"+(zips.size() > 1? "s are":"is")+" gzipped to: "+to+"\n");
            for (int le, i = 0, mx = zips.size(); i < mx; ++i) {
              String s = zips.get(i);
              if (!to.equals(s)) {
                rawContent(zos, s);
                txtA.appendText("Gzipped: "+s+"\n");
                ++cnt;
              }
            }
            txtA.appendText("Done! "+cnt+" file"+(cnt > 1?"s are":" is")+" gzipped\n\n");
          } else { // Append/Replace
            zos = new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(to, false)));
            //
            cnt = 0; pIdx = 0;
            int mx = zips.size();
            int rp[] = new int[mx];
            OUT: while (true) {
              String en = nextEntry( );
              if (en == null) break;
              int i = 0;
              for (String s : zips) {
                if (rp[i] == 0 && rawEntry(s).equals(en)) {
                  rawContent(zos, s);
                  rp[i] = 1; // replaced
                  ++cnt;
                  continue OUT;
                }
                ++i;
              }
              ++cnt;
              zos.write(buf, pRaw, eRaw);
              zos.flush();
            }
            int rep = 0, app = 0;
            for (int i = 0; i < mx; ++i) {
              String s = zips.get(i);
              if (!to.equals(s)) {
                if (rp[i] > 0) {
                  txtA.appendText("Replaced: "+s+"\n");
                  ++rep;
                } else {
                  rawContent(zos, s);
                  txtA.appendText("Appended "+s+"\n");
                  ++cnt;
                }
                ++app;
              }
            }
            txtA.appendText("Done! "+app+" file");
            if (app > 1) txtA.appendText("s are ");
            else txtA.appendText(" is ");
            if (rep == app) txtA.appendText("replaced");
            else if (rep == 0) txtA.appendText("appended");
            else txtA.appendText("appended or replaced");
            txtA.appendText(". Total gzipped Files: "+cnt+"\n\n");
          }
          if (zos != null) {
            zos.flush();
            zos.close();
          }
        }
With JZIPInputStream and JZIPOutputStream:
Java:
      int app = 0, rep = 0, mx = zips.size();
      JZIPOutputStream jos = new JZIPOutputStream(to, fMode, !ow);  // <--- new API
      String T = fMode? "ZIPPED":"GZIPPED";
      aLst = jos.entryList();
      int cnt = aLst.size();
      for (int i = 0; i < mx; ++i) {
        String fn = zips.get(i);
        int l = fn.indexOf(":"); // Windows?
        String en = l > 0? fn.substring(l+2):fn;
        if (wp && aLst.contains(en) || !wp && aLst.contains(en.replace(RAW,""))) {
          txtA.appendText("Replaced: "+fn+"\n");
          jos.replaceEntry(fn, wp);
          ++rep;
        } else {
          if (!ow) txtA.appendText("Appended "+fn+"\n");
          else txtA.appendText(T+" "+fn+"\n");
          jos.addEntry(fn, wp);
          ++cnt;
          ++app;
        }
      }
      jos.close();
      if (!ow) {
        txtA.appendText("Done! ");
        if (app > 0) {
          if (app > 1) txtA.appendText(app+" files are appended");
          else txtA.appendText(app+" file is appended");
        }
        if (rep > 0) {
          if (rep > 1) txtA.appendText(rep+" files are replaced");
          else txtA.appendText(rep+" file is replaced");
        }
        txtA.appendText(". Total "+T+" Files: "+cnt+"\n\n");
      } else txtA.appendText("Done! "+cnt+" file"+(cnt > 1?"s are ":" is ")+T+" \n\n");
As you see, the fMode is now one of the Constructor's parameters of JZIPOutputStream. The Screenshot:

JZIP_1.jpg

As usual, here is the package for download.
Have fun
Joe
 

Attachments

Sửa lần cuối:
  • Like
Reactions: ngtheanh.dev