Java,如果内容相同,则创建两个相同的zip文件

时间:2014-10-23 10:17:15

标签: java zip

我有这个,它适用于压缩和解压缩:

    public static final String SLASH = "/";
    public static void zip(int level, File zipfile, File... files) throws IOException {
            try (FileOutputStream fo = new FileOutputStream(zipfile); ZipOutputStream zo = new ZipOutputStream(fo)) {
                    zo.setLevel(level);

                    for (File file : files) {
                            zip("", file, zo);
                    }

                    zo.flush();
                    zo.finish();
                    zo.close();

                    // !!!!!!!! Tried these !!!!!!!!!
                    long time = Cal.date(1970, Cal.Month.JANUARY, 1).getTime();
                    zipfile.setLastModified(time);
                    Files.setAttribute(zipfile.toPath(), "lastAccessTime", FileTime.fromMillis(time) );
            }
    }

    public static File unzip(File zipfile, File to) throws IOException {
            ZipFile                         filezipped = new ZipFile( zipfile );
            Enumeration<? extends ZipEntry> entries    = filezipped.entries( ) ;

            while ( entries.hasMoreElements() ) {

                    ZipEntry zipEntry = entries.nextElement( )             ;
                    File     file     = new File( to, zipEntry.getName( ) );

                    if ( zipEntry.isDirectory() ) {
                            file.mkdirs();
                    }
                    else {
                            file.getParentFile().mkdirs();
                            try ( InputStream in = filezipped.getInputStream(zipEntry) ) {
                                    Files.copy( in, file.toPath() );
                            }
                    }
            }

            return zipfile;
    }

    private static void zip(String base, File file, ZipOutputStream zo) throws IOException {
            String path   = base + file.getName();
            if ( file.isDirectory() ) {
                    path += SLASH;

                    zo.putNextEntry( new ZipEntry(path) );

                    for (File ff : file.listFiles()) {
                            zip(path, ff, zo);
                    }

                    zo.closeEntry();

            } else {
                    zo.putNextEntry( new ZipEntry(path) );

                    Files.copy(file.toPath(), zo);

                    zo.closeEntry();
            }
    }

但是,即使文件内容不变,zip文件也会有不同的校验和。使用git提交文件时出现问题。

除非内容发生变化,否则我怎样才能确保每次压缩文件保持不变?

2 个答案:

答案 0 :(得分:4)

ZIP文件本身的时间戳无关紧要,但请尝试将ZIP条目的最后修改时间设置为常量值:

ZipEntry entry = new ZipEntry(path);
entry.setTime(0);

zo.putNextEntry(entry);

有关详细信息,请参阅setTime JavaDoc。


<强>更新

如果您的参赛作品的内容和顺序相同,上述内容确实可以解决问题。我查看了ZipOutputStream的源代码,并在putNextEntry方法中找到了以下内容:

if (e.time == -1) {
    e.setTime(System.currentTimeMillis());
}

因此,在将条目添加到流之前将time设置为0应该可以防止它被覆盖,并保持内容不变。

答案 1 :(得分:1)

我不确定你的Cal类正在做什么,但我怀疑它在内部正在创建一个Calendar实例并设置日期字段。您应该知道,如果您这样做,那么它仍将以当前时间结束,而不是00:00!因此,您很可能每次都获得相同的时间戳。

我只是试试

long time = 0;

而不是与日历实例混淆。