2017-04-10 25 views
1

サブフォルダにファイルを展開する際に問題が発生します。私が解凍する必要があるzipファイルには複数のフォルダがあり、解凍時にディレクトリ構造を維持しようとしています。Java:サブフォルダを含むフォルダを解凍する

package components; 

import java.io.BufferedOutputStream; 
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.ZipInputStream; 

/** 
* This utility extracts files and directories of a standard zip file to 
* a destination directory. 
* 
* 
*/ 
public class UnzipUtility { 
    /** 
    * Size of the buffer to read/write data 
    */ 
    private static final int BUFFER_SIZE = 4096; 
    /** 
    * Extracts a zip file specified by the zipFilePath to a directory specified by 
    * destDirectory (will be created if does not exists) 
    * @param zipFilePath 
    * @param destDirectory 
    * @throws IOException 
    */ 
    public void unzip(String zipFilePath, String destDirectory) throws IOException { 
     File destDir = new File(destDirectory); 
     if (!destDir.exists()) { 
      destDir.mkdir(); 
     } 
     ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath)); 

     ZipEntry entry = zipIn.getNextEntry(); 
     // iterates over entries in the zip file 
     while (entry != null) { 
      String filePath = destDirectory + File.separator + entry.getName(); 
      if (!entry.isDirectory()) { 
       // if the entry is a file, extracts it 
       extractFile(zipIn, filePath); 
       System.out.println(filePath); 
      } else { 
       // if the entry is a directory, make the directory 
       File dir = new File(filePath); 
       System.out.println(filePath); 
       dir.mkdir(); 
      } 
      zipIn.closeEntry(); 
      entry = zipIn.getNextEntry(); 
     } 
     zipIn.close(); 
    } 
    /** 
    * Extracts a zip entry (file entry) 
    * @param zipIn 
    * @param filePath 
    * @throws IOException 
    */ 
    private void extractFile(ZipInputStream zipIn, String filePath) throws IOException { 
     BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); 
     byte[] bytesIn = new byte[BUFFER_SIZE]; 
     int read = 0; 
     while ((read = zipIn.read(bytesIn)) != -1) { 
      bos.write(bytesIn, 0, read); 
     } 
     bos.close(); 
    } 
} 

出力コードは次のとおりです。問題は、ファイルDoD-DISA-logos-as-JPEG.jpgがサブフォルダになる子フォルダの一部であることです。したがって、パスはフォルダ/サブフォルダ/子フォルダ/ DoD-DISA-logos-as-JPEG.jpgにする必要があります。それは私が信じるIO例外を得るので、その子フォルダを含んでいません。

java.io.FileNotFoundException: /Users/user/Desktop/folder/subfolder/DoD-DISA-logos-as-JPEG.jpg (No such file or directory) 
    at java.io.FileOutputStream.open0(Native Method) 
    at java.io.FileOutputStream.open(FileOutputStream.java:270) 
    at java.io.FileOutputStream.<init>(FileOutputStream.java:213) 
    at java.io.FileOutputStream.<init>(FileOutputStream.java:101) 
    at components.UnzipUtility.extractFile(UnzipUtility.java:62) 
    at components.UnzipUtility.unzip(UnzipUtility.java:42) 
    at components.UnzipUtilityTest.main(UnzipUtilityTest.java:9) 
+1

'string filePath = destDirectory + File.separator + entry.getName();'パスは存在しますか?最初のエントリがファイルの場合、 'dir.mkdir'でディレクトリを作成していません – Flikk

答えて

2

あなたはentry.isDirectory()上またはZipEntryイテレータはすべてのフォルダ階層を一覧表示するという事実に頼るべきではありません。

zipファイル構造には、サブフォルダ階層をその名前に含むZipEntryファイルのみを含めることができます。例えば。 foo/bar/file.txtがためにこのようZipEntryなくfoo/foo/bar/

次のようになります。

  • ファイル、あなたは親ディレクトリを取得し、それがFile#mkdirs
  • ディレクトリに存在しない場合は、階層全体を作成する必要があり、 File#mkdirs

あなたのコードは何かに変換する必要がありますIKEはこと:

 if (!entry.isDirectory()) { 
      // if the entry is a file, extracts it 
      new File(filePath).getParentFile().mkdirs(); 
      extractFile(zipIn, filePath); 
      System.out.println(filePath); 
     } else { 
      // if the entry is a directory, make the directory 
      File dir = new File(filePath); 
      System.out.println(filePath); 
      dir.mkdirs(); 
     } 

私はzt-zipのような解凍/ジップに外部ライブラリを使用することをお勧めします。

+0

Nicolas、ありがとう。これは私のためにとてもうまく動作し、教育的でした。 – InTheShell

+0

あなたは大歓迎です! –

+1

アーカイブの操作用にApache Commons Compressもお勧めします(https://commons.apache.org/proper/commons-compress/index.html) – fandango

関連する問題