2012-07-11 40 views
6

我正在使用Apache Commons 1.4.1庫來壓縮和解壓縮".tar.gz"文件。如何使用Apache Commons解壓TAR文件

我在最後一位遇到問題 - 將TarArchiveInputStream轉換爲FileOutputStream

奇怪的是,它打破這條線:

FileOutputStream fout = new FileOutputStream(destPath); 

destPath是一個規範的路徑文件:C:\ Documents和Settings \管理員\我的文檔\ JavaWorkspace \ BackupUtility \未解壓\測試\子目錄\ testinsub.txt

錯誤產生:

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

任何想法它可能是什麼?爲什麼它無法找到路徑?

我附上下面的整個方法(其中大部分從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

不好意思問這個問題,但是我試着用你的代碼示例,並且看到它工作時給出了我正在使用的特定'gzip'文件。如果給定在inputStream上讀取的內容,沒有對'fout.write(...)進行任何調用,它是如何工作的?在[answer @ user1894600建議](http://stackoverflow.com/a/14211580/320399)中,他必須顯式調用'write(...)'並提供已讀入內存的字節數組。 – blong 2013-11-16 22:14:52

回答

5

一對夫婦一般點的,你爲什麼做巫術與File構造,那裏是一個perfectly usable constructor在這裏你可以定義的File要創建並給予父文件的名稱?

其次我不太確定窗口中的路徑是如何處理空白空間的。這可能是你的問題的原因。嘗試使用我上面提到的構造,看看它是否有差別:File destPath = new File(dest, tarEntry.getName());(假設File dest是一個正確的文件,並且存在並且是由您訪問

第三,你有File對象做任何事情之前,你應該檢查如果它存在,如果它是可訪問的。這將最終幫助你查明問題。

+0

感謝您的回覆。我決定重寫這個模塊,它效果很好。我已經接受了關於不使用File對象的建議,所以我會將您的答案標記爲正確的(基於原理) – Redandwhite 2012-07-21 10:58:23

+0

很高興幫助,並且希望最終它能夠正常工作。祝你好運:) – posdef 2012-07-22 23:04:41

+0

我使用相同的代碼來解壓.tar文件而不是.tar.gz。而我從這一行'新的文件(dest,tarEntry.getName())'文件內容不是文件名。我能做些什麼來獲取.tar – 2016-07-18 07:47:06

13

你的程序的Java堆空間錯誤。 所以我覺得有點變化需要。 這裏是代碼...

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

好l uck

+0

中的文件名所以,會發生堆空間錯誤,因爲當它聲明爲byte [] btoRead = new byte [(int)tarEntry.getSize()時,字節數組可能會過大) ];'? – blong 2013-11-16 22:22:08

+1

優秀的迴應。但是,應該修改以下'deskPath.createNewFile();'以創建父目錄if(!destPath.getParentFile())。exists()){ destPath.getParentFile()。mkdirs(); } destPath.createNewFile();' – 2015-09-08 16:01:46

相關問題