1

私の質問は本当に単純です。ディレクトリを圧縮しようとしている間の予期しない動作(または少なくとも私には予期しない) についてです。自分で作成した次の方法があります (私は「例外やその他すべてを処理していません。これは、(今では)その方法を学ぶためにこれを行っているだけなので、安定性は「それほど重要ではない」ためです)、コードは次のとおりです。

public static void zipDirectory(File srcDirectory, File zipFile) throws IllegalArgumentException {
    if (!srcDirectory.isDirectory()) {
        throw new IllegalArgumentException("The first parameter (srcDirectory) MUST be a directory.");
    }
    int bytesRead;
    byte[] dataRead  = new byte[1000];
    BufferedInputStream in = null;
    ZipOutputStream zOut;
    try {
        zOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
        for (File f : srcDirectory.listFiles()) {
            if (f.isDirectory()) {
                FileUtilities.zipInnerDirectory(f,zOut);
            }else {
                in = new BufferedInputStream(new FileInputStream(f.getAbsolutePath()), 1000);
                zOut.putNextEntry(new ZipEntry(f.getPath())); 
                while((bytesRead = in.read(dataRead,0,1000)) != -1) {
                    zOut.write(dataRead, 0, bytesRead);
                }
                zOut.closeEntry();
            }
        }
        zOut.flush();
        zOut.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private static void zipInnerDirectory(File dir, ZipOutputStream zOut) throws IllegalArgumentException {
    if (!dir.isDirectory()) {
        throw new IllegalArgumentException("The first parameter (srcDirectory) MUST be a directory.");
    }
    BufferedInputStream in = null;
    int bytesRead;
    byte[] dataRead  = new byte[1000];
    try {
        for (File f : dir.listFiles()) {
            if (f.isDirectory()) {
                FileUtilities.zipInnerDirectory(f,zOut);
            }else {
                in = new BufferedInputStream(new FileInputStream(f.getAbsolutePath()), 1000);
                zOut.putNextEntry(new ZipEntry(f.getPath())); 
                while((bytesRead = in.read(dataRead,0,1000)) != -1) {
                    zOut.write(dataRead, 0, bytesRead);
                }
                zOut.closeEntry();
            }
        }
        zOut.flush();
        zOut.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

私が言ったように、私の最高のコーディングではないので、コードを判断しないでください (または、少なくとも厳密になりすぎないでください ;))、私はそれがはるかに優れていることを知っています。「予期しない動作」はこれです。次のディレクトリがあるとしましょう。

  • H:\MyDir1\MyDir2\MyDirToZip

そのパス ( ) で作成されたファイルをパラメーターとして送信すると、new File("H:\\MyDir1\\MyDir2\\MyDirToZip")すべてが正常に機能し、zip が正常に作成されます。zip 内のファイルを開く (解凍する) と、次の構造になります。

  • H:\MyDir1\MyDir2\MyDirToZip

私がただ中を見つけることを期待していたとき:

  • \MyDirToZip

H: \MyDir1 \MyDir2 なしは「不要」です (ところで、適切な順序で互いに 1 つだけ含まれています。つまり、それらに含まれる他のファイルは圧縮されていないため、不要であると言えます)問題は、私が間違っていることは何ですか?構造をsrcDirectoryに圧縮したいだけだと指定するにはどうすればよいですか?

4

1 に答える 1

2
zOut.putNextEntry(new ZipEntry(f.getPath())); 

これが問題になるはずです。f.getPath()ルートディレクトリ(おそらく現在の作業ディレクトリ)に相対的なパスを返しますが、zipするディレクトリには相対的ではありません。zipディレクトリから相対パスを取得する方法を理解する必要があります。おそらくこれで次のようになります。

new ZipEntry(f.getAbsolutePath().substring(zipDir.getAbsolutePath().length()))

または、ルートディレクトリを追加する場合:

new ZipEntry(zipDir.getName() + "/"
             + f.getAbsolutePath().substring(zipDir.getAbsolutePath().length()))
于 2012-11-16T15:59:31.927 に答える