Programm zum Unzippen funktioniert nicht.

  • Themenstarter Themenstarter Shlyakh
  • Beginndatum Beginndatum
S

Shlyakh

Guest
Ich übe gerade IO-Streams und habe mal überlegt eine Klasse zu schreiben, die einen Zipordner auspackt und dessen Files in ein Verzeichnis schreibt.

Ich Instantiiere die Klasse, die das tun soll inner Main-Mathode (MainX, da Testversion).
Code:
import java.util.zip.*;

import java.util.*;

import java.io.*;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.*;
import org.apache.commons.io.*;

class MainX
{

public static void main(String[] args) throws FileNotFoundException, IOException, ArchiveException
  {

ZIPopenerX zo = new ZIPopenerX();

//Ja, ich benutze Windows und so sieht mein Pfad zu dem Ordner aus, den ich auspacken will...
zo.unZip(new ZipFile("C:\\Programme\\Java\\jdk1.7.0_15\\bin\\ordner.zip"));


  }

}


Hier die Klasse:

Code:
import java.util.*;
import java.io.*;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.compress.archivers.*;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.io.*;

class ZIPopenerX extends UNZIP{

  

HashMap<String,File> unZip( ZipFile inputFile) throws FileNotFoundException, IOException, ArchiveException 
{

//Ich will die aus der ZIPDatei die Ordner auch in diese HashMap setzen, aber das is nicht das Problem. 
HashMap<String,File> unzippedFiles = new HashMap<String,File>();

//Ich willo alle Entris meiner ZIP-Inputdatei schlussendlich alle in einen Ordner schreiben.
File outputDir = new File("C:\\Programme"); outputDir.mkdir();

//Und hier mache ich mir einen ZIP-Inputstream und wrappe einen ZipArchiveInputSTream drumrum.
ZipInputStream is = new ZipInputStream(new FileInputStream(new File(inputFile.getName()))); 
ZipArchiveInputStream debInputStream = (ZipArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("zip", is);

ZipArchiveEntry entry = null;

      
      while ((entry = (ZipArchiveEntry)debInputStream.getNextEntry()) != null){ 
      //Jede Datei in meiner ZIP-Datei mache ich so zu einem File-Objekt.
        File outputFile = new File(entry.getName());

        if (entry.isDirectory()) {
            if (!outputFile.exists()) {
                if (!outputFile.mkdirs()) {
                    throw new IllegalStateException(String.format("Couldn't create directory %s.", outputFile.getAbsolutePath()));
                }
            }
        } 
         else { //Hier will ich den Ordner mit den Entries vollschreiben über einen Outputstream.
                //Das scheint nicht zu klappen. Ich kann nicht mal den Ordner finden. 
            OutputStream outputFileStream = new FileOutputStream(outputDir); 
           IOUtils.copy(debInputStream, outputFileStream);
            outputFileStream.close();
        }

//*********Ab hier isses eigentich uninteressant und für mein Problem irrelevant.
    
        unzippedFiles.put(outputFile.getName().substring(0,outputFile.getName().length()-4),outputFile);  
 

    }
    debInputStream.close(); 

    System.out.println(unzippedFiles);//--> Leer :(
    return unzippedFiles;
}

}


Kompilieren tut es. Das Problem ist, dass das Verzeichnis nicht gemacht wird, und dass in selbiges auch nix geschrieben wird. Habe ich da beim Fileoutputstream nicht verstanden?


Code:
import java.util.*;
import java.io.*;
import java.util.zip.*;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.*;
import org.apache.commons.io.*;

abstract class UNZIP
{ 

abstract HashMap<String,File> unZip(final ZipFile inputFile) throws FileNotFoundException, IOException, ArchiveException;  

}
 
Welches Betriebssystem verwendest du? Ab Windows Vista könnte dich UAC davon abhalten, einfach Ordner und Dateien unter C:\Programme anzulegen.
Versuch mal einen anderen Pfad anzugeben, z.B. C:\Users\USERNAME\AppData\Local\Temp.
 
Hab XP 5. 1 Build2600.

Ich hab mal diesen Pfad genommen:

C:\\Dokumente und Einstellungen\\Benutzer1\\Desktop

, da ich "AppData\Local\Temp" nicht finden konnte, Benutzer 1 bin ich.

...aber das hat nichts gebracht leider.
 
Ich habe momentan leider kein funktionierendes eclipse zur Verfügung, aber mit etwas Glück kann ich morgen früh mal schauen, ob ich deinen Code ans Laufen bekomme, wenn es bis dahin noch keine Lösung gibt :).
 
Ich finde das super nett, dass Du mir hilfst; ich habe mir unterdessen überlegt, ob es zur Erreichung des Ziels (ZIP-Ordner auspacken und in ein VZ schrieben) auch einfachere Wege gibt. Ich habe mir als auspackende Klasse sowas überlegt:

Code:
import java.io.*;
import java.util.*;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

class ZIPopenerX extends UNZIP{

  

HashMap<String,File> unZip( ZipFile inputFile) throws FileNotFoundException, IOException 
{

HashMap<String,File> res = new HashMap<String,File>();

File outputDir = new File("C:\\Dokumente und Einstellungen\\Benutzer1\\Desktop"); outputDir.mkdir(); 

Enumeration e = inputFile.entries();
  while( e.hasMoreElements() ) {
      FileInputStream fin = new FileInputStream(e.nextElement().toString());
      ZipInputStream zin = new ZipInputStream(fin);
      ZipEntry ze = null;
      while ((ze = zin.getNextEntry()) != null) {
        
        res.put(ze.getName(),new File(ze.getName()));

        FileOutputStream fout = new FileOutputStream(outputDir);
        for (int c = zin.read(); c != -1; c = zin.read()) {
          fout.write(c);
        }
        zin.closeEntry();
        fout.close();
      }
      zin.close();
}
return res;
    
}

}


...und als mainmethode dann dieses:

Code:
import java.util.zip.*;
import java.util.*;
import java.io.*;

class MainX
{

public static void main(String[] args) throws FileNotFoundException, IOException, ArchiveException
  {

ZIPopenerX zo = new ZIPopenerX();
zo.unZip(new ZipFile(args[0]));


  }

}

Aaaaaber: Jetzt motzt der Compiler wieder - jetzt sagt er:

FileNotFoundException: ordner
Das System kann die angegebene Datei nicht finden.

Meine Zipdatei heißt ordner.zip und ist im selben VZ wie die Mainklasse.

Als ich ordner als ZipFile instantiieren wollte mit new ZipFile(ABSOLUTE_PFADANGABE_ZU_ORDNER) kam derselbe Fehler. Auch bei als ich der Methode unzip new ZipFile(Ordnername) übergeben wollte kam der Fehler. Das ist rätselhaft, und aus der Lektüre der API-Doku bin ich auch nciht wirklich schlau geworden.
 
...hm, nach viel Herumprobieren habe ich mir jetz ne Lösung ausm Netz gerippt. Ich schreibe das für ne Anwendung, diejenige Klasse, die eine ZipFile zum Auspacken bekommt, sieht nun so aus:

Code:
import java.util.*;
import java.io.*;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZIPopener {

  public void copyInputStream(InputStream in, OutputStream out)
  throws IOException
  {
    byte[] buffer = new byte[1024];
    int len;

    while((len = in.read(buffer)) >= 0)
      out.write(buffer, 0, len);

    in.close();
    out.close();
  }

  HashMap<String,File> unZip(ZipFile zipFile) {

  HashMap<String,File> unzippedFiles = new HashMap<String,File>();

    Enumeration entries;

    try {

      entries = zipFile.entries();

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

        if(entry.isDirectory()) {
          
          (new File(entry.getName())).mkdir();
          continue;
        }

        unzippedFiles.put(entry.getName(),new File(entry.getName())); 
        copyInputStream(zipFile.getInputStream(entry),
           new BufferedOutputStream(new FileOutputStream(entry.getName())));
      }

      zipFile.close();
    } catch (IOException ioe) {
      ioe.printStackTrace();
      
    }
  return unzippedFiles; 
 }

}
 
Super, dass es jetzt doch funktioniert :)!

Ich hatte vorhin noch ein wenig herumprobiert und war mit deiner ersten Lösung soweit gekommen, dass die Archivdateien korrekt gelesen wurden, allerdings der Pfad zum Entpacken scheinbar noch nicht ganz korrekt war.
Wenn es dich interessiert, die Änderungen waren in der Klasse ZipOpenerX:

Code:
ZipInputStream is = new ZipInputStream(new BufferedInputStream(
                new FileInputStream(new File(inputFile.getName()))));
        ZipArchiveInputStream debInputStream = (ZipArchiveInputStream) new ArchiveStreamFactory()
                .createArchiveInputStream("zip", is);

        ZipEntry entry = null;

        while ((entry = is.getNextEntry()) != null) {
            // Jede Datei in meiner ZIP-Datei mache ich so zu einem File-Objekt.
            File outputFile = new File(entry.getName());

            // Hier wird noch der Pfad des ZIP-Archivs eingesetzt
            if (entry.isDirectory()) {
                if (!outputFile.mkdirs())
                    throw new IllegalStateException(String.format(
                            "Couldn't create directory %s.",
                            outputFile.getAbsolutePath()));
            } else { // Hier will ich den Ordner mit den Entries vollschreiben
                        // über einen Outputstream.
                        // Das scheint nicht zu klappen. Ich kann nicht mal den
                        // Ordner finden.
                OutputStream outputFileStream = new FileOutputStream(outputDir
                        + File.separator + entry.getName());
                IOUtils.copy(debInputStream, outputFileStream);
                outputFileStream.close();
            }

Wie gesagt noch nicht 100% korrekt, aber der Rest sollte recht einfach zu beheben sein.
 
Zurück
Oben