2012-07-11 12 views
6

Ich verwende die Apache Commons 1.4.1-Bibliothek zum Komprimieren und Dekomprimieren von ".tar.gz" Dateien.So entpacken Sie eine TAR-Datei mit Apache Commons

Ich habe Probleme mit dem letzten Bit - eine TarArchiveInputStream in eine FileOutputStream umwandeln.

Seltsamer, es bricht auf dieser Linie: C:

FileOutputStream fout = new FileOutputStream(destPath); 

destPath eine Datei mit einem Canonical Pfad ist \ Dokumente und Einstellungen \ Administrator \ Eigene Dateien \ JavaWorkspace \ BackupUtility \ untarred \ Test \ subdir \ testinsub.txt

Fehler produziert:

Exception in thread "main" java.io.IOException: The system cannot find the path specified 

Irgendeine Idee, was es sein könnte? Und warum kann es den Weg nicht finden?

Ich füge die ganze Methode unten an (die meisten davon sind von here aufgehoben).

private void untar(File dest) throws IOException { 
    dest.mkdir(); 
    TarArchiveEntry tarEntry = tarIn.getNextTarEntry(); 
    // tarIn is a TarArchiveInputStream 
    while (tarEntry != null) {// create a file with the same name as the tarEntry 
     File destPath = new File(dest.toString() + System.getProperty("file.separator") + tarEntry.getName()); 
     System.out.println("working: " + destPath.getCanonicalPath()); 
     if (tarEntry.isDirectory()) { 
      destPath.mkdirs(); 
     } else { 
      destPath.createNewFile(); 
      FileOutputStream fout = new FileOutputStream(destPath); 
      tarIn.read(new byte[(int) tarEntry.getSize()]); 
      fout.close(); 
     } 
     tarEntry = tarIn.getNextTarEntry(); 
    } 
    tarIn.close(); 
} 
+0

Peinlich zu fragen, aber ich habe versucht, mit Ihrem Code-Beispiel und sah es funktioniert eine bestimmte 'gzip' Datei, mit der ich arbeitete. Wie funktioniert das ohne Aufruf von 'fout.write (...)' angesichts des Inhalts, der auf dem inputStream gelesen wurde? Im [answer @ user1894600 suggest] (http://stackoverflow.com/a/14211580/320399) muss er explizit 'write (...)' aufrufen und das Byte-Array bereitstellen, das in den Speicher eingelesen wurde. – blong

Antwort

5

Ein paar allgemeine Punkte, warum tun Sie Voodoo mit dem File Konstruktor tun, wo ein perfectly usable constructor dort ist, wo Sie den Namen der File Sie definieren eine übergeordnete Datei erstellen und geben?

Zweitens bin ich mir nicht sicher, wie leere Räume in Pfaden in Windows behandelt werden. Es könnte die Ursache für Ihre Probleme sein. Versuchen Sie, den Konstruktor ich oben erwähnt und sehen, ob es einen Unterschied macht. File destPath = new File(dest, tarEntry.getName()); (unter der Annahme, dass File dest eine richtige Datei ist und existiert und ist mit dem Sie

Drittens, bevor Sie etwas tun, mit einem File Objekt sollten Sie überprüfen, wenn es vorhanden ist, und wenn es zugänglich ist. das wird letztlich helfen, das Problem lokalisieren.

+0

Danke für Ihre Antwort. Ich habe beschlossen, das Modul neu zu schreiben und es funktioniert großartig. Ich habe Ihren Ratschlag, nicht mit dem File-Objekt zu spielen, angenommen, und deshalb werde ich Ihre Antwort als die richtige markieren (basierend auf dem Prinzip) – Redandwhite

+0

Froh, dass es geholfen hat, und hoffe, dass alles am Ende gut ausgeht. Viel Glück :) – posdef

+0

Ich verwende den gleichen Code, um eine .tar-Datei entpacken, nicht die .tar.gz. Und ich bekomme von dieser Zeile 'neue Datei (dest, tarEntry.getName())' den Dateiinhalt nicht den Dateinamen. Was kann ich tun, um den Dateinamen innerhalb der .tar –

13

Ihr Programm die Fehler Java Heap-Speicher hat. so glaube ich, eine kleine Änderung nötig. hier ist der Code ...

public static void uncompressTarGZ(File tarFile, File dest) throws IOException { 
    dest.mkdir(); 
    TarArchiveInputStream tarIn = null; 

    tarIn = new TarArchiveInputStream(
       new GzipCompressorInputStream(
        new BufferedInputStream(
         new FileInputStream(
          tarFile 
         ) 
        ) 
       ) 
      ); 

    TarArchiveEntry tarEntry = tarIn.getNextTarEntry(); 
    // tarIn is a TarArchiveInputStream 
    while (tarEntry != null) {// create a file with the same name as the tarEntry 
     File destPath = new File(dest, tarEntry.getName()); 
     System.out.println("working: " + destPath.getCanonicalPath()); 
     if (tarEntry.isDirectory()) { 
      destPath.mkdirs(); 
     } else { 
      destPath.createNewFile(); 
      //byte [] btoRead = new byte[(int)tarEntry.getSize()]; 
      byte [] btoRead = new byte[1024]; 
      //FileInputStream fin 
      // = new FileInputStream(destPath.getCanonicalPath()); 
      BufferedOutputStream bout = 
       new BufferedOutputStream(new FileOutputStream(destPath)); 
      int len = 0; 

      while((len = tarIn.read(btoRead)) != -1) 
      { 
       bout.write(btoRead,0,len); 
      } 

      bout.close(); 
      btoRead = null; 

     } 
     tarEntry = tarIn.getNextTarEntry(); 
    } 
    tarIn.close(); 
} 

gut l uck

+0

So würde der Heap-Speicher-Fehler auftreten, weil das Byte-Array möglicherweise zu groß ist, wenn es als Byte deklariert wird [] btoRead = neues Byte [(int) tarEntry.getSize() ]; '? – blong

+1

Ausgezeichnete Antwort. Das folgende 'deskPath.createNewFile();' sollte jedoch geändert werden, um das übergeordnete Verzeichnis 'if (! DestPath.getParentFile() zu erstellen.exists()) { destPath.getParentFile(). mkdirs(); } destPath.createNewFile(); ' –

Verwandte Themen