使用java“压缩”目录时添加了不必要的文件结构?

时间:2012-11-16 15:52:43

标签: java compression zip

我的问题非常简单,关于意外行为(或者至少对我来说是意料之外的)当我尝试压缩目录时,我有以下方法,我已经创建了我自己(我很清楚我没有处理异常和所有这些东西,这是因为(到现在为止)我只是这样做以学习如何做到这样稳定“并不是非常重要”),这里是代码:

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中的文件时,他们有下一个结构:

  • H:\ MyDir1 \ MyDir2 \ MyDirToZip

当我期待在里面找到时:

  • \ MyDirToZip

没有H:\ MyDir1 \ MyDir2这是“不必要的”(BTW他们只是以适当的顺序包含一个,我的意思是,其中的其他文件没有压缩,这就是为什么我说他们是不必要的)所以问题是,我做错了什么?如何指定我只想将结构压缩到 srcDirectory

1 个答案:

答案 0 :(得分:2)

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

这应该是问题所在。 f.getPath()将返回一个相对于某个根目录(可能是您当前正在工作的目录)的路径,但不会相对于您正在压缩的目录。你需要弄清楚从zip目录获取相对路径的方法,可能会这样做:

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

或者,如果您想要添加根目录:

new ZipEntry(zipDir.getName() + "/"
             + f.getAbsolutePath().substring(zipDir.getAbsolutePath().length()))