zip entpacken Problem

TimoP

Grünschnabel
Hallo,

leider konnten mir die 3 themen mit zip nicht wirklich weiter helfen ich habe zwar den code von dort zum testen mal verwendet

Code:
package updater;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.sound.sampled.*;
import java.io.*;
import java.util.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;



public class Zip
{
//	Arbeitsflaeche() arb=new Arbeitsflaeche();
	double ProGes;  // Bisher geschaffte Prozentzahl
	double ProStep;	// In dem Intervall wird hochgezählt

  public void extractArchive(File archive, File destDir) throws Exception {
//          new msg.setText("Test");//	  	  arb.msg.setText("Daten werden entpackt");
		  if (!destDir.exists()) {
				  destDir.mkdir();
		  }

		  ZipFile zipFile = new ZipFile(archive);
		  Enumeration entries = zipFile.entries();

		  byte[] buffer = new byte[16384];
		  int len;

		  //Hier wird das Intervall ausgerechnet
		  ProStep=100 / zipFile.size() ;
		  while (entries.hasMoreElements()) {  

				  ZipEntry entry = (ZipEntry) entries.nextElement();

				  String entryFileName = entry.getName();

				  if (entry.isDirectory()) {
						 File dir = new File(destDir, entryFileName);
//						  jLabel15.setText("Kopiere Dateien..." + dir.getName());
			  ProGes=ProGes+ProStep;
//						  this.setTitle("Sea Wars - " + ProGes + "%");
						  if (!dir.exists()) {
								 dir.mkdir();
						  }
				  } else {

						 BufferedOutputStream bos = new BufferedOutputStream(
								  new FileOutputStream(new File(destDir, entryFileName)));

				  BufferedInputStream bis = new BufferedInputStream(zipFile
						   .getInputStream(entry));

						 while ((len = bis.read(buffer)) > 0) {
								 bos.write(buffer, 0, len);
						  }

						  bos.flush();
						  bos.close();
						  bis.close();
				  }
		//Hier nochmal deine Anzeige auf 100% setzen
		  }
  }

Leider geht aber der aufruf nicht bei mir

es kommt immer
java.io.FileNotFoundException: c:\temp\kltrend\data\KLR.MDB (Das System kann den angegebenen Pfad nicht finden)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at updater.Zip.extractArchive(Zip.java:57)

Mein auf ruf ist

Code:
try 
{
new Zip().extractArchive(new File("c:/temp/"+pname+".zip"), new File("c:/temp/"));
} 
catch (Exception e) 
{
e.printStackTrace();
}
 
Hallo!

Wenn du Archive entpackst du Einträge mit gespeicherten Pfadangaben enthalten musst du diese Pfade natürlich auch anlegen...
Java:
File dir = new File(destDir + directoryPrefixForCurrentZipEntry);
        if(!dir.exists()){
            dir.mkdirs();
        }

Gruß Tom
 
HI,

den eintrag habe ich ja bereits drin

bekomm den fehler in der zeile

new FileOutputStream(new File(destDir, entryFileName)));


Die ordner ab /kltrend sind im zip verzeichniss drin
 
Zuletzt bearbeitet:
Hallo!

Der alte Code klappt nur bei den Archiven richtig bei denen die Verzeichniseinträge in der Liste der enthaltenen Dateien (entries) ganz oben kommen... einige Archive scheinen aber nicht so gebaut zu sein... siehe das ICUXXXX.jar in Eclipse

So sollte es jedoch "immer" gehen:
Java:
package de.tutorials.training;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class ZipArchiveExtractor {

	protected int bufferSizeInBytes = 16384;

	public static void main(String[] args) throws Exception {
		File archiveFile = new File("C:/development/java/glassfish-3.1/glassfish/lib/javahelp.jar");
		File targetDirectory = new File("c:/tmp/x");
		
		new ZipArchiveExtractor().extractArchive(archiveFile, targetDirectory);
	}

	public void extractArchive(File archive, File destDir) throws Exception {

		if (!destDir.exists()) {
			destDir.mkdir();
		}

		ZipFile zipFile = null;
		try {
			zipFile = new ZipFile(archive);
			Enumeration<? extends ZipEntry> entries = zipFile.entries();

			byte[] buffer = new byte[bufferSizeInBytes];
			int len;
			while (entries.hasMoreElements()) {
				ZipEntry entry = (ZipEntry) entries.nextElement();

				String entryFileName = entry.getName();

				File dir = buildDirectoryHierarchyFor(entryFileName, destDir);

				if (!dir.exists()) {
					dir.mkdirs();
				}

				if (!entry.isDirectory()) {
					File targetFile = new File(destDir, entryFileName);
					BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile));
					BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));

					while ((len = bis.read(buffer)) > 0) {
						bos.write(buffer, 0, len);
					}

					bos.flush();
					bos.close();
					bis.close();
				}
			}
		} finally {
			if (zipFile != null) {
				zipFile.close();
			}
		}

	}

	private File buildDirectoryHierarchyFor(String entryName, File destDir) {
		int lastIndex = entryName.lastIndexOf('/');
		String internalPathToEntry = entryName.substring(0, lastIndex + 1);
		return new File(destDir, internalPathToEntry);
	}
}
//edit Bugfix zipFile immer schließen, danke miho20

Gruß Tom
 
Hallo an alle,

Ist zwar schon lange her. Aber ich habe gerade nach einer Lösung zum Entpacken gesucht und bin hier fündig geworden. Danke Tom und danke Tutorials.de!

Allerdings hat der Code von Tom hat einen fiesen Bug. Wenn man ein hohes IO-Aufkommen hat, fällt auf, dass zipFile nie geschlossen wird. Das kann u.U. fatal sein, wenn mit den entpackten Daten oder dem Archiv direkt weitergearbeitet wird. Das führt zu inkonsistenten Daten. Also einfach zipFile in einem try/catch/finally-Block korrekt schließen. Dann funktioniert der Code sehr gut.

Danke & Gruß,
Michael
 
Ist heute dank Autocloseable nicht mehr nötig. Einfach das aktuelle Java7 verwenden ... dann funktioniert der Code da auch heute immer noch perfekt. *Warum Tom das damals vergessen hat weis ich nicht.*
 
Zurück