Zipelés és kicsomagolás Java-ban

1. Áttekintés

Ebben a gyors bemutatóban megvitatjuk, hogyan lehet egy fájlt archívumba tömöríteni, és hogyan kell kibontani az archívumot - mindezt a Java által biztosított alapvető könyvtárak segítségével.

Ezek az alapvető könyvtárak a java.util.zip csomag - ahol megtalálhatjuk az összes tömörítéssel és kicsomagolással kapcsolatos segédprogramot.

2. Zip egy fájlt

Először vessünk egy pillantást egy egyszerű műveletre - egyetlen fájl tömörítése.

Példánkként egy fájl nevű fájlt fogunk tömöríteni test1.txt nevű archívumba tömörítve.zip.

Természetesen először lemezről fogunk hozzáférni a fájlhoz - nézzük meg:

public class ZipFile {public static void main (String [] args) dobja az IOException {String sourceFile = "test1.txt"; FileOutputStream fos = új FileOutputStream ("tömörített.zip"); ZipOutputStream zipOut = new ZipOutputStream (fos); File fileToZip = új File (sourceFile); FileInputStream fis = új FileInputStream (fileToZip); ZipEntry zipEntry = új ZipEntry (fileToZip.getName ()); zipOut.putNextEntry (zipEntry); bájt [] bájt = új bájt [1024]; int hossza; while ((hossz = fis.read (byte))> = 0) {zipOut.write (byte, 0, hossz); } zipOut.close (); fis.close (); fos.close (); }}

3. Zip több fájlt

Ezután nézzük meg, hogyan lehet több fájlt egy zip fájlba tömöríteni. Összenyomjuk test1.txt és test2.txt -ba multiCompressed.zip:

public class ZipMultipleFiles {public static void main (String [] args) dobja az IOException {List srcFiles = Arrays.asList ("test1.txt", "test2.txt"); FileOutputStream fos = new FileOutputStream ("multiCompressed.zip"); ZipOutputStream zipOut = new ZipOutputStream (fos); for (String srcFile: srcFiles) {File fileToZip = új fájl (srcFile); FileInputStream fis = új FileInputStream (fileToZip); ZipEntry zipEntry = új ZipEntry (fileToZip.getName ()); zipOut.putNextEntry (zipEntry); bájt [] bájt = új bájt [1024]; int hossza; while ((hossz = fis.read (byte))> = 0) {zipOut.write (byte, 0, hossz); } fis.close (); } zipOut.close (); fos.close (); }}

4. Zip egy könyvtárat

Most beszéljük meg, hogyan lehet egy egész könyvtárat tömöríteni. Be fogjuk címezni zipTest -ba dirCompressed.zip :

public class ZipDirectory {public static void main (String [] args) dobja az IOException {String sourceFile = "zipTest"; FileOutputStream fos = new FileOutputStream ("dirCompressed.zip"); ZipOutputStream zipOut = new ZipOutputStream (fos); File fileToZip = új File (sourceFile); zipFile (fileToZip, fileToZip.getName (), zipOut); zipOut.close (); fos.close (); } private static void zipFile (File fileToZip, String fileName, ZipOutputStream zipOut) dobja az IOException {if (fileToZip.isHidden ()) {return; } if (fileToZip.isDirectory ()) {if (fájlNév.endsWith ("/")) {zipOut.putNextEntry (új ZipEntry (fájlnév)); zipOut.closeEntry (); } else {zipOut.putNextEntry (új ZipEntry (fájlnév + "/")); zipOut.closeEntry (); } Fájl [] gyerekek = fileToZip.listFiles (); for (File childFile: children) {zipFile (childFile, fileName + "/" + childFile.getName (), zipOut); } Visszatérés; } FileInputStream fis = új FileInputStream (fileToZip); ZipEntry zipEntry = új ZipEntry (fájlnév); zipOut.putNextEntry (zipEntry); bájt [] bájt = új bájt [1024]; int hossza; while ((hossz = fis.read (byte))> = 0) {zipOut.write (byte, 0, hossz); } fis.close (); }}

Vegye figyelembe, hogy:

  • Az alkönyvtárak tömörítéséhez rekurzív módon ismételjük őket.
  • Minden alkalommal, amikor találunk egy könyvtárat, hozzáfűzzük a nevét az utódokhoz ZipEntry név a hierarchia mentéséhez.
  • Minden üres könyvtárhoz létrehozunk egy könyvtárbejegyzést is

5. Csomagolja ki az archívumot

Csomagoljuk ki egy archívumot, és bontsuk ki annak tartalmát.

Ebben a példában kibontjuk a csomagolást tömörítve.zip nevű új mappába unzipTest.

Nézzük meg:

public class UnzipFile {public static void main (String [] args) dobja az IOException {String fileZip = "src / main / resources / unzipTest / compressed.zip"; Fájl destDir = új fájl ("src / main / resources / unzipTest"); bájt [] puffer = új bájt [1024]; ZipInputStream zis = új ZipInputStream (új FileInputStream (fileZip)); ZipEntry zipEntry = zis.getNextEntry (); while (zipEntry! = null) {// ...} zis.closeEntry (); zis.close (); }}

Benne míg hurok, mindegyiket végig fogjuk iterálni ZipEntry és először ellenőrizze, hogy könyvtár-e. Ha igen, akkor a könyvtár segítségével hozzuk létre a könyvtárat mkdirs () módszer; különben folytatjuk a fájl létrehozását:

while (zipEntry! = null) {fájl newFile = newFile (destDir, zipEntry); if (zipEntry.isDirectory ()) {if (! newFile.isDirectory () &&! newFile.mkdirs ()) {dobjon új IOException-t ("Nem sikerült létrehozni a könyvtárat" + newFile); }} else {// javítás a Windows által létrehozott archívumokhoz File parent = newFile.getParentFile (); if (! parent.isDirectory () &&! parent.mkdirs ()) {dob új IOException ("Nem sikerült létrehozni a könyvtárat" + szülő); } // fájl tartalmának írása FileOutputStream fos = new FileOutputStream (newFile); int len; míg ((len = zis.read (puffer))> 0) {fos.write (puffer, 0, len); } fos.close (); } zipEntry = zis.getNextEntry (); }

Az egyik megjegyzés, hogy a más ág, először azt is ellenőrizzük, hogy létezik-e a fájl szülőkönyvtára. Erre szükség van a Windows rendszeren létrehozott archívumokhoz, ahol a gyökérkönyvtáraknak nincs megfelelő bejegyzésük a zip fájlban.

Egy másik kulcsfontosságú pont látható a új fájl() módszer:

public static File newFile (File destinationDir, ZipEntry zipEntry) dobja az IOException-t {File destFile = új File (destinationDir, zipEntry.getName ()); Karakterlánc destDirPath = célDir.getCanonicalPath (); Karakterlánc destFilePath = destFile.getCanonicalPath (); if { } return destFile; }

Ez a módszer megakadályozza, hogy fájlokat írjon a fájlrendszerbe a célmappán kívül. Ezt a biztonsági rést Zip Slipnek hívják, és erről itt olvashat bővebben.

6. Következtetés

Ez az oktatóanyag bemutatta, hogyan használhatjuk a Java könyvtárakat a fájlok tömörítéséhez és kicsomagolásához.

Ezeknek a példáknak a megvalósítása megtalálható a GitHub oldalon.