2012-07-11 16 views
6

Używam biblioteki Apache Commons 1.4.1 do kompresowania i dekompresji plików ".tar.gz".Jak rozpakować plik TAR za pomocą Apache Commons

Mam problem z ostatnim bitem - przekształcenie TarArchiveInputStream w FileOutputStream.

Co dziwne, to łamanie na tej linii:

FileOutputStream fout = new FileOutputStream(destPath); 

destPath to plik z kanoniczną ścieżkę: C: \ Documents and Settings \ Administrator \ Moje dokumenty \ JavaWorkspace \ BackupUtility \ rozpakowany \ test \ podkatalog \ testinsub.txt

błąd wymienić:

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

Każdy pomysł, co to może być? I dlaczego nie jest w stanie znaleźć ścieżki?

Załączam całą poniższą metodę (większość z nich została usunięta z here).

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

Zakłopotany, aby o to zapytać, ale próbowałem użyć próbki kodu i zobaczyłem, że działa z danym plikiem 'gzip', z którym pracowałem. Jak to działa bez wywoływania 'fout.write (...)' biorąc pod uwagę zawartość odczytaną w inputStream? W [answer @ user1894600 sugestiach] (http://stackoverflow.com/a/14211580/320399) musi jawnie wywołać 'write (...)' i dostarczyć tablicę bajtów, która została odczytana w pamięci. – blong

Odpowiedz

5

Kilka ogólnych punktów, dlaczego robisz voodoo z konstruktora File, gdzie istnieje perfectly usable constructor gdzie można zdefiniować nazwę File chcesz stworzyć i dać pliku nadrzędnego?

Po drugie, nie jestem zbyt pewny, jak obsługiwane są puste przestrzenie w ścieżkach w oknach. To może być przyczyną twoich problemów. Spróbuj użyć konstruktora wspomniałem powyżej i zobacz, czy to robi różnicę. File destPath = new File(dest, tarEntry.getName()); (zakładając, że File dest jest właściwy plik, a istnieje i jest dostępny przez Ciebie

trzecie, zanim zrobisz cokolwiek z File obiektu należy sprawdzić jeśli istnieje, a jeśli jest ona dostępna. to będzie ostatecznie pomóc zidentyfikować problem.

+0

Dzięki za odpowiedź. Postanowiłem przerobić moduł i działa świetnie. Przyjęłam twoją radę, że nie gram z obiektem File, więc mam zamiar oznaczyć twoją odpowiedź jako poprawną (na podstawie zasady). – Redandwhite

+0

Cieszę się, że pomogło, i mam nadzieję, że wszystko dobrze się skończy. Powodzenia :) – posdef

+0

Używam tego samego kodu, aby rozpakować plik .tar, a nie .tar.gz. I dostaję z tej linii "nowy plik (dest, tarEntry.getName())" treść pliku, a nie nazwa pliku. Co mogę zrobić, aby uzyskać nazwę pliku wewnątrz .tar –

13

Twój program ma błąd java przestrzeń sterty. więc myślę, że trochę zmiana potrzebne. tutaj jest kod ...

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(); 
} 

dobre l uck

+0

Tak więc wystąpił błąd przestrzeni sterty, ponieważ tablica bajtowa jest potencjalnie zbyt duża, gdy jest zadeklarowana jako 'byte [] btoRead = new byte [(int) tarEntry.getSize() ] ;; – blong

+1

Doskonała odpowiedź. Jednak poniższe 'deskPath.createNewFile();' należy zmodyfikować, aby utworzyć katalog nadrzędny 'if (! DestPath.getParentFile().exists()) { destPath.getParentFile(). mkdirs(); } destPath.createNewFile(); ' –

Powiązane problemy