Zipsovanie a rozbaľovanie v Jave

1. Prehľad

V tomto rýchlom návode si povieme, ako zazipovať súbor do archívu a ako archív rozbaliť - to všetko pomocou základných knižníc poskytovaných Java.

Tieto základné knižnice sú súčasťou java.util.zip balíček - kde nájdeme všetky pomocné programy súvisiace so zipsom a rozbalením.

2. Komprimujte súbor

Najprv sa pozrime na jednoduchú operáciu - zazipovanie jedného súboru.

Pre náš príklad tu skomprimujeme súbor s názvom test1.txt do archivovaného pomenovaného stlačený.zip.

Samozrejme najskôr pristúpime k súboru z disku - pozrime sa:

public class ZipFile {public static void main (String [] args) hodí IOException {String sourceFile = "test1.txt"; FileOutputStream fos = nový FileOutputStream ("compressed.zip"); ZipOutputStream zipOut = nový ZipOutputStream (fos); Súbor fileToZip = nový súbor (sourceFile); FileInputStream fis = nový FileInputStream (fileToZip); ZipEntry zipEntry = nový ZipEntry (fileToZip.getName ()); zipOut.putNextEntry (zipEntry); byte [] bytes = nový bajt [1024]; int dĺžka; while ((length = fis.read (bytes))> = 0) {zipOut.write (bytes, 0, length); } zipOut.close (); fis.close (); fos.close (); }}

3. Komprimujte viac súborov

Ďalej sa pozrime, ako skomprimovať viac súborov do jedného súboru zip. Stlačíme test1.txt a test2.txt do multiCompressed.zip:

public class ZipMultipleFiles {public static void main (String [] args) hodí IOException {List srcFiles = Arrays.asList ("test1.txt", "test2.txt"); FileOutputStream fos = nový FileOutputStream ("multiCompressed.zip"); ZipOutputStream zipOut = nový ZipOutputStream (fos); pre (String srcFile: srcFiles) {File fileToZip = new File (srcFile); FileInputStream fis = nový FileInputStream (fileToZip); ZipEntry zipEntry = nový ZipEntry (fileToZip.getName ()); zipOut.putNextEntry (zipEntry); byte [] bytes = nový bajt [1024]; int dĺžka; while ((length = fis.read (bytes))> = 0) {zipOut.write (bytes, 0, length); } fis.close (); } zipOut.close (); fos.close (); }}

4. Zip adresár

Teraz poďme diskutovať o tom, ako komprimovať celý adresár. Budeme adresár zipTest do dirCompressed.zip :

public class ZipDirectory {public static void main (String [] args) hodí IOException {String sourceFile = "zipTest"; FileOutputStream fos = nový FileOutputStream ("dirCompressed.zip"); ZipOutputStream zipOut = nový ZipOutputStream (fos); Súbor fileToZip = nový Súbor (sourceFile); zipFile (fileToZip, fileToZip.getName (), zipOut); zipOut.close (); fos.close (); } private static void zipFile (File fileToZip, String fileName, ZipOutputStream zipOut) hodí IOException {if (fileToZip.isHidden ()) {return; } if (fileToZip.isDirectory ()) {if (fileName.endsWith ("/")) {zipOut.putNextEntry (new ZipEntry (fileName)); zipOut.closeEntry (); } else {zipOut.putNextEntry (nový ZipEntry (názov súboru + "/")); zipOut.closeEntry (); } Súbor [] deti = fileToZip.listFiles (); for (File childFile: children) {zipFile (childFile, fileName + "/" + childFile.getName (), zipOut); } návrat; } FileInputStream fis = nový FileInputStream (fileToZip); ZipEntry zipEntry = nový ZipEntry (názov súboru); zipOut.putNextEntry (zipEntry); byte [] bytes = nový bajt [1024]; int dĺžka; while ((length = fis.read (bytes))> = 0) {zipOut.write (bytes, 0, length); } fis.close (); }}

Poznač si to:

  • Na zazipovanie podadresárov ich rekurzívne iterujeme.
  • Zakaždým, keď nájdeme adresár, pripojíme jeho meno k potomkom ZipEntry názov uložiť hierarchiu.
  • Tiež vytvoríme záznam v adresári pre každý prázdny adresár

5. Rozbaľte archív

Poďme teraz archív rozbaliť a extrahovať jeho obsah.

V tomto príklade rozbalíme stlačený.zip do nového priečinka s názvom unzipTest.

Pozrime sa na to:

public class UnzipFile {public static void main (String [] args) throws IOException {String fileZip = "src / main / resources / unzipTest / compressed.zip"; File destDir = new File ("src / main / resources / unzipTest"); byte [] buffer = nový bajt [1024]; ZipInputStream zis = nový ZipInputStream (nový FileInputStream (fileZip)); ZipEntry zipEntry = zis.getNextEntry (); while (zipEntry! = null) {// ...} zis.closeEntry (); zis.close (); }}

Vnútri zatiaľ čo slučka, budeme iterovať cez každú ZipEntry a najskôr skontrolujte, či ide o adresár. Ak je, vytvoríme adresár pomocou mkdirs () metóda; v opačnom prípade budeme pokračovať v vytváraní súboru:

while (zipEntry! = null) {File newFile = newFile (destDir, zipEntry); if (zipEntry.isDirectory ()) {if (! newFile.isDirectory () &&! newFile.mkdirs ()) {hodiť novú IOException ("Nepodarilo sa vytvoriť adresár" + newFile); }} else {// oprava archívov vytvorených v systéme Windows File parent = newFile.getParentFile (); if (! parent.isDirectory () &&! parent.mkdirs ()) {hodiť novú IOException ("Nepodarilo sa vytvoriť adresár" + rodič); } // zapisovanie obsahu suboru FileOutputStream fos = new FileOutputStream (newFile); int len; while ((len = zis.read (buffer))> 0) {fos.write (buffer, 0, len); } fos.close (); } zipEntry = zis.getNextEntry (); }

Jedna poznámka je, že na inak vetva, najskôr tiež kontrolujeme, či existuje nadradený adresár súboru. Je to nevyhnutné pre archívy vytvorené v systéme Windows, kde koreňové adresáre nemajú zodpovedajúcu položku v súbore zip.

Ďalším kľúčovým bodom je dokument newFile () metóda:

public static File newFile (File destinationDir, ZipEntry zipEntry) throws IOException {File destFile = new File (destinationDir, zipEntry.getName ()); Reťazec destDirPath = destinationDir.getCanonicalPath (); Reťazec destFilePath = destFile.getCanonicalPath (); if (! destFilePath.startsWith (destDirPath + File.separator)) {throw new IOException ("Entry is outside of the target dir:" + zipEntry.getName ()); } návrat destFile; }

Táto metóda chráni pred zápisom súborov do súborového systému mimo cieľového priečinka. Táto chyba sa volá Zip Slip a viac si o nej môžete prečítať tu.

6. Záver

Tento tutoriál ilustroval, ako môžeme používať knižnice Java na operácie zipovania a rozbaľovania súborov.

Implementáciu týchto príkladov možno nájsť na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found