Zippen

maGG

Bekanntes Mitglied
Ich möchte lernen, wie man Ordnerstrukturen, mit Inhalt zippt. Dazu habe ich mir folgendes Video angeschaut:
Und ich habe mir auf java2s das hier angeschaut: http://www.java2s.com/Code/Java/Fil...toryincludingitssubdirectoriesrecursively.htm
Ich nehme mal den Code aus Letzteren:
Java:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Main {
  private static void zipDir(String zipFileName, String dir) throws Exception {
    File dirObj = new File(dir);
    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
    System.out.println("Creating : " + zipFileName);
    addDir(dirObj, out);
    out.close();
  }

  static void addDir(File dirObj, ZipOutputStream out) throws IOException {
    File[] files = dirObj.listFiles();
    byte[] tmpBuf = new byte[1024];

    for (int i = 0; i < files.length; i++) {
      if (files[i].isDirectory()) {
        addDir(files[i], out);
        continue;
      }
      FileInputStream in = new FileInputStream(files[i].getAbsolutePath());
      System.out.println(" Adding: " + files[i].getAbsolutePath());
      out.putNextEntry(new ZipEntry(files[i].getAbsolutePath()));
      int len;
      while ((len = in.read(tmpBuf)) > 0) {
        out.write(tmpBuf, 0, len);
      }
      out.closeEntry();
      in.close();
    }
  }

  public static void main(String[] args) throws Exception {
    zipDir(args[0], args[1]);
  }
}
Ich finde das ist ziemlich kompliziert! Kennt ihr vielleicht ne bessere Seite, mit nem leichteren Beispiel?
Muss ich das in zwei Methoden aufteilen? Ich fänds praktischer, wenn ich alles in ein Button schreiben könnte.
File[] files = dirObj.listFiles(); was macht das??
byte[] tmpBuf = new byte[1024]; wofür brauch ich das? Ist das so ne Art Größer, in der die Sachen gespeichert werden?
out.closeEntry(); was macht dieses closeEntry?
Muss ich Schleifen benutzen?

Was ich eigentlich machen will ist ein Ordner auf dem Desktop zu zippen, in dem Ordner sind dann noch 3 Dateien drin. Den Pfad dafür habe ich auch schon:
Java:
String homeDirectory = new JFileChooser().getFileSystemView().getHomeDirectory().toString();
                String dir = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim();
Aber dann weiß ich nicht weiter :/ Habt ihr vielleicht ein Beispiel für mich, aus dem ich dann ableiten könnte, wie ich es bauen kann?

LG
 

JStein52

Top Contributor
Mhmmm ... du hast doch oben ein Beispiel. Wenn dir zwei Methoden zuviel sind schreibst du halt alles in eine.

Edit:
Einfacher ist es aber wie es oben ist. Denn so kann man den Directory-Baum besser rekursiv durchgehen.
 

maGG

Bekanntes Mitglied
Mein bisheriger Versuch:
Java:
    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                          
            try{
                String homeDirectory = new JFileChooser().getFileSystemView().getHomeDirectory().toString();
                String dir = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim();
                String pfadBat = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + "Signatur.bat";
                String pfadHtml = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + vorname.trim() + " " + nachname.trim() + ".html";
                String pfadTxt = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + vorname.trim() + " " + nachname.trim() + ".txt";
               
                FileOutputStream fos = new FileOutputStream(dir + ".zip");
                ZipOutputStream zos = new ZipOutputStream(fos);
               
                String file = dir;
                String bat = pfadBat;
                String html = pfadHtml;
                String txt = pfadTxt;
               
                addDir(zos,file);
                addDir(zos, bat);
                addDir(zos, html);
                addDir(zos, txt);
                               
            }catch(FileNotFoundException eZip){
                eZip.printStackTrace();
            } catch (IOException ex) {
                Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
            }
    }
Java:
        static void addDir(ZipOutputStream zos, String fileName) throws IOException {
           
            File file = new File(fileName);   
            FileInputStream fis = new FileInputStream(file);
            ZipEntry zipEntry = new ZipEntry(fileName);
            zos.putNextEntry(zipEntry);
           
            byte[] bytes = new byte[1024];
            int length;
            while((length = fis.read(bytes))>=0){
                zos.write(bytes, 0, length);
            }
            zos.closeEntry();
            fis.close();           
        }
Das einzige was bisher funktioniert ist, dass er einen zip Ordner erstellt. Dieser ist jedoch ohne Inhalt. Wie kann ich denn einen Ordner darin erstellen, in dem dann noch Dateien sind? Der Ordner hat ja keine .endung, deswegen kann ich als String auch nicht .txt oder sowas schreiben, wie funktioniert das mit Ordner?
 

maGG

Bekanntes Mitglied
hmmm kann mir zu mindest jemand sagen was die folgende Zeile genau macht?
Code:
addDir(zos,bat);
Bzw. da muss ich doch den Pfad angeben, von der der Dateien die bereits existiert oder?
Im Moment ist es so, dass mir einer Zip Order erstellt wird - jedoch ohne Inhalt.
der e.printStackTrace() gibt mir leider nichts aus! Von daher vermute ich, dass es an den angegebenen Pfad liegen könnte. Oder aber ich habe diesen Teil der Methode falsch interpretiert.

Weiterhin würde ich gerne wissen, wie man auf dieser Weise, einen Order im Zip Ordner erzeugt. Also was ich will ist folgendes:
Ziporder -> Ordner -> .bat,.htm,.txt-Datei
 

JStein52

Top Contributor
addDir(zos,bat); würde dem Zip-File die Datei die in "bat" übergeben wird hinzufügen. Aber eine solche Datei gibt es ja sicher nicht. Guck dir mal genau an was du in "bat" stehen hast !!
 

maGG

Bekanntes Mitglied
Also bei mir ist bat ein String, mit dem Werte homeDirectory\vorname nachname\Signatur.bat
Die Parameter vorname und nachname sind variable und wurden bereits benutzt für die Erstellung der Dateien. Die zip-Methode soll dann noch die Option bieten, den gerade erstellten Ordner, mit Inhalt, zu zippen.

Ich habe das so verstanden, dass ich für den String den Pfad meiner existierenden Datei + Name der existierenden Datei angeben müsste. Habe ich das so falsch verstanden?
 

maGG

Bekanntes Mitglied
Es kommt keine Exception, das ist ja mein Problem.
Das steht doch da oben:
Java:
 String pfadBat = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + "Signatur.bat";
Java:
String bat = pfadBat;
Java:
addDir(zos, bat);
Der String sieht so aus ?
Oder wie meintest du das?
 
X

Xyz1

Gast
zippen/unzippen?
Diesen Link gelesen: http://stackoverflow.com/questions/9324933/what-is-a-good-java-library-to-zip-unzip-files ?
Frage sehr ähnlich,
hast du Linux?
Dann über das Terminal möglich,
bei Windows fest verankert im System,
dann über GNU core utilities möglich,
hatte so etwas auch mal geschrieben, aber unzippen - und zusammenhängend auf das HDD schreiben,
Problem: JVM stößt da an die Grenzen, weil nicht mal einfach so 10 GB Arbeitsspeicher zugesichert werden darf.
Also, erst überlegen, was du möchtest, dann entsprechende Lib. wählen - oder System"werkzeug".
 

JStein52

Top Contributor
Ach übrigens, vielleicht liegt es daran: du darfst als Entry-Namen keine Absoluten Pfadnamen verwenden.
c:\Desktop\....\datei.txt geht nicht, Desktop\...\datei.txt geht
 
X

Xyz1

Gast
Oder halt raw selber schreiben, hatte ich mal einen Preis mit gewonnen. :D (5 oder 10 € gab's, das weiß ich nicht mehr.)
 

JStein52

Top Contributor
Und du solltest hinter dem letzten addDir(...) noch ein zos.close(); einstreuen sonst endest du mit einem üngültigen Zip-File
 

maGG

Bekanntes Mitglied
Also es geht um Windows! Wie gebe ich denn homeDirectory ohne die Festplatte an?
@DerWissende ich schau mir das später mal in Ruhe an deinen Link, bei GNU core utilities, und Problem mit JVM bin ich übrigens ausgestiegen. Verstehe nur Bahnhof :D
 

JStein52

Top Contributor
Problem mit JVM bin ich übrigens ausgestiegen. Verstehe nur Bahnhof
Dein Code funktioniert ja im Prinzip. Du darfst halt nur relative Pfadnamen für die Entries angeben. Und du musst auch nicht explizit irgendwelche Directories in der Zip-Datei anlegen, die legt er automatisch aus den Pfadangaben deiner Entries an. Also wenn du einen Entry mit dem Namen hugo\emil\datei.txt anlegst werden die Directories hugo und emil angelegt. Wie gesagt, dein Code ist da schon richtig
 

maGG

Bekanntes Mitglied
Hmm irgendwie egal was ich versuche; es klappt nicht :/ :/ Ich will keine neuen Pfäde anlegen. Ich will die Pfäde der bereits existierenden Dateien angeben. Das mit dem System.getProperty("user.home") funktioniert bei mir nicht.
 

maGG

Bekanntes Mitglied
Java:
            try{
                String homeDirectory = new JFileChooser().getFileSystemView().getHomeDirectory().toString();
                String userHome = (System.getProperty("user.home") + "\\Desktop").substring(3);
                String dir = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim();
                String pfadBat = userHome + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + "Signatur.bat";
                String pfadHtm = userHome + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + vorname.trim() + " " + nachname.trim() + ".htm";
                String pfadTxt = userHome + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + vorname.trim() + " " + nachname.trim() + ".txt";
               
                //jTextAreaAusgabe.setText(pfadHtm);
               
                FileOutputStream fos = new FileOutputStream(dir + ".zip");
                ZipOutputStream zos = new ZipOutputStream(fos);
               
                addDir(zos, pfadBat);
                addDir(zos, pfadHtm);
                addDir(zos, pfadTxt);
               
                zos.close();
                               
            }catch(FileNotFoundException eZip){
                eZip.printStackTrace();
            } catch (IOException ex) {
                //Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
                ex.printStackTrace();
        }
Sieht jetzt so bei mir aus. Funktioniert aber immer noch nicht. Zip Ordner lässt sich nicht öffnen und er meckert bei den addDir Zeilen. Bei pfaHtm kommt jetzt "Users\david\Desktop\test test\test test.htm" raus, was ja richtig wäre. Aber es funktionier nicht. Ich sitze daran jetzt schon 6 Stunden und es funktioniert nicht. Bin echt kurz davor einfach alles zu löschen und auf die zip Funktion zu verzichten, bin grad so unendlich genervt grrrrrr
 

JStein52

Top Contributor
Ich vermute mal er findet die Dateien nicht mehr weil du dein Programm nicht auf dem Desktop ausführst sondern irgendwo. Und dann stimmt natürlich der Pfad: Users\david\Desktop\test test\test test.htm nicht !
du musst den Pfad innerhalb von addDir, dort wo du den EntryNamen zusammenbastelst ändern ! Der Teil davor war ja richtig.
 

JStein52

Top Contributor
nein, dann findet er die Datei genau so wenig. Wie soll denn bei diesem Beispiel "Users\david\Desktop\test test\test test.htm" der Inhalt der Zip-Datei aussehen ?
 

maGG

Bekanntes Mitglied
Ich verstehe dich nicht :oops:
"Pfad innerhalb von addDir" verstehe nicht was du damit meinst.
  1. Button klick -> Signatur wird erstellt -> Users\david\Desktop\vorname nachname (Ordner)
  2. -> Users\david\Desktop\vorname nachname\Signatur.bat
  3. -> Users\david\Desktop\vorname nachname\vorname nachname.htm
  4. -> Users\david\Desktop\vorname nachname\vorname nachname.txt
  5. Button klick -> zippen -> Users\david\Desktop\vorname nachname.zip
  6. -> Users\david\Desktop\vorname nachname.zip\vorname nachname(Ordner)\Signatur.bat
  7. -> Users\david\Desktop\vorname nachname.zip\vorname nachname(Ordner)\vorname nachname.htm
  8. -> Users\david\Desktop\vorname nachname.zip\vorname nachname(Ordner)\vorname nachname.txt
so hatte ich mir das gedacht :confused:
 

JStein52

Top Contributor
dann ändere mal das mit dem user.home wieder zurück auf
Code:
                String homeDirectory = new JFileChooser().getFileSystemView().getHomeDirectory().toString();
                String dir = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim();
                String pfadBat = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + "Signatur.bat";
                String pfadHtml = homeDirectory + "\\" + vorname.trim() + " " + nachname.trim() + "\\" + vorname.trim() + " " + nachname.trim() + ".html";
                String pfadTxt = homeDirectory +  "\\" + vorname.trim() + " " + nachname.trim() + ".txt";
dann hast du wieder richtige Pfadnamen unter denen er die Dateien auch findet. Dann änderst du in addDir diese Zeile wie folgt:

Code:
ZipEntry zipEntry = new ZipEntry(file.getAbsolutePath().replace(new File(file.getParent()).getParent()+"\\", ""));
 

maGG

Bekanntes Mitglied
OMG es funktioniert! Die eine Zeile verstehe ich nur so halb, aber OMG es funktioniert! Danke vielmals JStein52! Wenn ich in deine Nähe wäre, würde ich dir ein Eis ausgeben :D

Danke auch euch anderen für die Hilfe! :)
 

JStein52

Top Contributor
Na siehst du. Die mysteriöse Zeile entfernt aus dem Kompletten Pfadnamen den vorderen Teil bis zum Parent-Directory. Das bleibt bestehen.
schau es dir nochmal in Ruhe an.
 

Ähnliche Java Themen

Neue Themen


Oben