Dateien in ein Zip-Archiv hinzufügen

zerix

Hausmeister
Moderator
Hallo,
ich habe ein Zip-Programm geschrieben.
Beim erstellen eines Zip-Archives kann man sich das Kompressionslevel auswählen. Wenn ich jetzt Dateien einem Archiv hinzufügen möchte, brauche ich das gleiche Kompressionslevel, wie beim Erstellen des Archivs, da das Programm sonst ne Exception auswirft. Ich weiß aber nicht wie ich rausbekommen soll mit welchem Kompressionslevel das Archiv komprimiert wurde.

Kann mir bitte einer helfen oder hat jemand eine andere Idee
 
Zuletzt bearbeitet:
Hallo!

Schau mal hier:
Code:
/**
 * 
 */
package de.tutorials;

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

/**
 * @author Tom
 * 
 */
public class ZipFileExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		File archiveFile = new File("e:/foo.zip");
		File file = new File("e:/tmp/bar.txt");

		addFileToArchive(file, archiveFile);
	}

	public static void addFileToArchive(File file, File archiveFile)
			throws Exception {

		File tmpFile = new File(String.valueOf(System.currentTimeMillis()));

		ZipFile zipSrc = new ZipFile(archiveFile);

		ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tmpFile));

		Enumeration srcEntries = zipSrc.entries();
		while (srcEntries.hasMoreElements()) {
			ZipEntry entry = (ZipEntry) srcEntries.nextElement();
			zos.putNextEntry(entry);

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

			while (bis.available() > 0) {
				zos.write(bis.read());
			}
			zos.closeEntry();

			bis.close();
		}

		ZipEntry newEntry = new ZipEntry(file.getName());
		zos.putNextEntry(newEntry);

		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
				file));
		while (bis.available() > 0) {
			zos.write(bis.read());
		}
		zos.closeEntry();

		zos.finish();

		zos.close();

		zipSrc.close();

		archiveFile.delete();

		tmpFile.renameTo(archiveFile);

	}

}

Gruß Tom
 
Da kommt leider der gleiche Fehler. Soweit ich erkenne ist das fast der gleiche Quelltext wie meiner, bis auf den BufferedInputStream, da hab ich nur nen InputStream

Exception in thread "main" java.util.zip.ZipException: invalid entry compressed size (expected 1318 but got 1316 bytes)
at java.util.zip.ZipOutputStream.closeEntry(Unknown Source)
at ZipFileExample.addFileToArchive(ZipFileExample.java:46)
at ZipFileExample.main(ZipFileExample.java:23)

Ich weiß, es an unterschiedlichen Kompressionsraten liegt, aber ich weiß nicht wie ich raus bekommen soll, mit welcher Kompressionsrate ein Archiv komprimiert wurde. Oder geht das auch anders?
 
Hallo!

Also bei mir funktionierts... unter Windows XP. Wenn ich mit Winzip 8.1 eine Datei mit maximaler Kompressionsrate packe und mit meinem Beispiel eine Textdatei hinzufüge klappt's einwandfrei.

Gruß Tom
 
Ich hab es gerade mal mit einer Evaluations Version von WinZip 9.0 und mit meinem Prog probiert und ich bekomme jedesmal den gleichen Fehler.
Ich benutze auch Windows XP.
Ich hab das ganze auch schon auf einem anderen Rechner probiert und da kommt auch der gleiche Fehler und viel falsch machen kann man da ja nicht.

Trotzdem danke für deine Hilfe
 
Hallo!

Ich hab das Beispiel nun mal mit Winzip 9.0 ausprobiert und es läuft einwandfrei durch...
Ich erzeuge mit Winzip eine Archiv mit einer 2 kbyte großen Textdatei. Die Kompressionsrate setze ich dabei auf Maximum (portable). Anschließend füge ich über den Beispielcode eine 1 kbyte große Datei hinzu.

Gruß Tom
 
Klar, bei TXT oder ähnlichen Dateien ist es fast egal wie hoch die Kompressionrate eingestellt ist, weil sich da bei der kompression fast nie was ändert. Versuch es mal mit mehreren verschiedenen Dateien.
 
Hallo!

Habs jetzt mal mit einem 36 MB jpeg Image versucht (liegt im foo.zip) und eine exe Datei hinzugefügt.

Funktioniert jetzt einwandfrei :)
Code:
/**
 * 
 */
package de.tutorials;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * @author Tom
 * 
 */
public class ZipFileExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		File archiveFile = new File("e:/foo.zip");
		File file = new File("c:/tmp/Firefox Setup 1.0.3.exe");

		addFileToArchive(file, archiveFile);
	}

	public static void addFileToArchive(File file, File archiveFile)
			throws Exception {

		File tmpFile = new File(String.valueOf(System.currentTimeMillis()));

		ZipFile zipSrc = new ZipFile(archiveFile);

		ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tmpFile));

		byte[] buffer = new byte[32756];
		int len = 0;

		Enumeration srcEntries = zipSrc.entries();
		while (srcEntries.hasMoreElements()) {
			ZipEntry entry = (ZipEntry) srcEntries.nextElement();

			ZipEntry newEntry = new ZipEntry(entry.getName());

			zos.putNextEntry(newEntry);

			InputStream is = zipSrc.getInputStream(entry);

			while ((len = is.read(buffer)) > 0) {
				zos.write(buffer, 0, len);
			}

			zos.flush();
			is.close();
		}

		ZipEntry newEntry = new ZipEntry(file.getName());
		zos.putNextEntry(newEntry);

		InputStream is = new FileInputStream(file);

		long size = 0;
		while ((len = is.read(buffer)) > 0) {
			zos.write(buffer, 0, len);
		}

		zos.closeEntry();
		zos.finish();
		zos.close();
		zipSrc.close();
		archiveFile.delete();
		tmpFile.renameTo(archiveFile);
	}

}

Gruß Tom
 
Geil, es funktioniert.
Könnteste mir bitte noch erklären woran es gelegen hat
 
Hallo!

Man muss einfach einen neuen ZipEntry erzeugen, der so heißt wie der alte ...
Code:
ZipEntry newEntry = new ZipEntry(entry.getName());
zos.putNextEntry(newEntry);
Dabei darf man jedoch nicht die Werte für size und compressedSize übernehmen, da diese scheinbar neu berechnet werden und dann leicht von den vorherigen abweichen können.

Gruß Tom
 
Zurück