Zippen en uitpakken in Java
1. Overzicht
In deze korte tutorial bespreken we hoe je een bestand in een archief kunt zippen en hoe je het archief kunt uitpakken - allemaal met behulp van kernbibliotheken die door Java worden geleverd.
Deze kernbibliotheken maken deel uit van het java.util.zip pakket - waar we alle aan zip en unzipping gerelateerde hulpprogramma's kunnen vinden.
2. Zip een bestand
Laten we eerst eens kijken naar een simpele handeling: het zippen van een enkel bestand.
Voor ons voorbeeld hier zullen we een bestand met de naam test1.txt in een gearchiveerde naam gecomprimeerd.zip. We zullen natuurlijk eerst het bestand vanaf schijf openen - laten we eens kijken: Laten we vervolgens kijken hoe u meerdere bestanden in één zipbestand kunt zippen. We zullen comprimeren test1.txt en test2.txt in multiCompressed.zip: Laten we nu bespreken hoe u een hele directory kunt zippen. We zullen directory zipTest in dirCompressed.zip : Let daar op: Laten we nu een archief uitpakken en de inhoud ervan uitpakken. Voor dit voorbeeld zullen we unzippen gecomprimeerd.zip in een nieuwe map met de naam unzipTest. Laten we eens kijken: Binnen in de terwijl lus, we zullen elk doorlopen ZipEntry en controleer eerst of het een directory is. Als dat het geval is, maken we de map met de mkdirs () methode; anders gaan we door met het maken van het bestand: Een opmerking hier is dat op de anders branch, controleren we ook eerst of de bovenliggende directory van het bestand bestaat. Dit is nodig voor archieven die zijn gemaakt op Windows, waar de root-mappen geen overeenkomstige vermelding in het zip-bestand hebben. Een ander belangrijk punt is te zien in de nieuw bestand() methode: Deze methode beschermt tegen het schrijven van bestanden naar het bestandssysteem buiten de doelmap. Deze kwetsbaarheid heet Zip Slip en je kunt er hier meer over lezen. Deze tutorial illustreerde hoe we Java-bibliotheken kunnen gebruiken voor het zippen en uitpakken van bestanden. De implementatie van deze voorbeelden is te vinden op GitHub.openbare klasse ZipFile {openbare statische leegte hoofd (String [] args) gooit IOException {String sourceFile = "test1.txt"; FileOutputStream fos = nieuwe FileOutputStream ("gecomprimeerd.zip"); ZipOutputStream zipOut = nieuwe ZipOutputStream (fos); File fileToZip = nieuw bestand (sourceFile); FileInputStream fis = nieuwe FileInputStream (fileToZip); ZipEntry zipEntry = nieuwe ZipEntry (fileToZip.getName ()); zipOut.putNextEntry (zipEntry); byte [] bytes = nieuwe byte [1024]; int lengte; while ((length = fis.read (bytes))> = 0) {zipOut.write (bytes, 0, length); } zipOut.close (); fis.close (); fos.close (); }}
3. Zip meerdere bestanden
openbare klasse ZipMultipleFiles {openbare statische leegte hoofd (String [] args) gooit IOException {List srcFiles = Arrays.asList ("test1.txt", "test2.txt"); FileOutputStream fos = nieuwe FileOutputStream ("multiCompressed.zip"); ZipOutputStream zipOut = nieuwe ZipOutputStream (fos); voor (String srcFile: srcFiles) {File fileToZip = nieuw bestand (srcFile); FileInputStream fis = nieuwe FileInputStream (fileToZip); ZipEntry zipEntry = nieuwe ZipEntry (fileToZip.getName ()); zipOut.putNextEntry (zipEntry); byte [] bytes = nieuwe byte [1024]; int lengte; while ((length = fis.read (bytes))> = 0) {zipOut.write (bytes, 0, length); } fis.close (); } zipOut.close (); fos.close (); }}
4. Zip een directory
openbare klasse ZipDirectory {openbare statische leegte hoofd (String [] args) gooit IOException {String sourceFile = "zipTest"; FileOutputStream fos = nieuwe FileOutputStream ("dirCompressed.zip"); ZipOutputStream zipOut = nieuwe ZipOutputStream (fos); File fileToZip = nieuw bestand (sourceFile); zipFile (fileToZip, fileToZip.getName (), zipOut); zipOut.close (); fos.close (); } privé statisch ongeldig zipFile (File fileToZip, String fileName, ZipOutputStream zipOut) gooit IOException {if (fileToZip.isHidden ()) {return; } if (fileToZip.isDirectory ()) {if (fileName.endsWith ("/")) {zipOut.putNextEntry (nieuwe ZipEntry (bestandsnaam)); zipOut.closeEntry (); } else {zipOut.putNextEntry (nieuwe ZipEntry (bestandsnaam + "/")); zipOut.closeEntry (); } Bestand [] kinderen = fileToZip.listFiles (); voor (File childFile: children) {zipFile (childFile, fileName + "/" + childFile.getName (), zipOut); } terugkeer; } FileInputStream fis = nieuwe FileInputStream (fileToZip); ZipEntry zipEntry = nieuwe ZipEntry (bestandsnaam); zipOut.putNextEntry (zipEntry); byte [] bytes = nieuwe byte [1024]; int lengte; while ((length = fis.read (bytes))> = 0) {zipOut.write (bytes, 0, length); } fis.close (); }}
5. Pak een archief uit
public class UnzipFile {public static void main (String [] args) gooit IOException {String fileZip = "src / main / resources / unzipTest / gecomprimeerd.zip"; Bestand destDir = nieuw bestand ("src / main / resources / unzipTest"); byte [] buffer = nieuwe byte [1024]; ZipInputStream zis = nieuwe ZipInputStream (nieuwe FileInputStream (fileZip)); ZipEntry zipEntry = zis.getNextEntry (); while (zipEntry! = null) {// ...} zis.closeEntry (); zis.close (); }}
while (zipEntry! = null) {File newFile = newFile (destDir, zipEntry); if (zipEntry.isDirectory ()) {if (! newFile.isDirectory () &&! newFile.mkdirs ()) {gooi nieuwe IOException ("Kan map niet maken" + newFile); }} else {// fix voor door Windows gemaakte archieven Bestand ouder = newFile.getParentFile (); if (! parent.isDirectory () &&! parent.mkdirs ()) {throw nieuwe IOException ("Aanmaken map mislukt" + parent); } // schrijf bestandsinhoud FileOutputStream fos = nieuwe FileOutputStream (newFile); int len; while ((len = zis.read (buffer))> 0) {fos.write (buffer, 0, len); } fos.close (); } zipEntry = zis.getNextEntry (); }
openbaar statisch bestand newFile (bestand bestemmingsmap, zipEntry zipEntry) gooit IOException {bestand destFile = nieuw bestand (bestemmingsmap, zipEntry.getnaam ()); String destDirPath = destinationDir.getCanonicalPath (); String destFilePath = destFile.getCanonicalPath (); if (! destFilePath.startsWith (destDirPath + File.separator)) {throw new IOException ("Entry bevindt zich buiten de doelmap:" + zipEntry.getName ()); } retourneer destFile; }
6. Conclusie