Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java,如果内容相同,则创建两个相同的zip文件_Java_Zip - Fatal编程技术网

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

Java,如果内容相同,则创建两个相同的zip文件,java,zip,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 Zi

我有这个,它可以很好地进行压缩和解压缩:

    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();
            }
    }
公共静态最终字符串斜杠=“/”;
公共静态voidzip(int级别、文件zipfile、文件…文件)引发IOException{
try(FileOutputStream fo=新的FileOutputStream(zipfile);zipoutstream zo=新的zipoutstream(fo)){
zo.setLevel(level);
用于(文件:文件){
zip(“”,文件,zo);
}
zo.flush();
zo.finish();
zo.close();
//!!!!!!!!!试过这些!!!!!!!!!
long time=Cal.date(1970年,Cal.Month.JANUARY,1.getTime();
zipfile.setLastModified(时间);
Files.setAttribute(zipfile.toPath(),“lastAccessTime”,FileTime.fromMillis(time));
}
}
公共静态文件解压(文件zipfile,文件到)引发IOException{
ZipFile filezipped=新的ZipFile(ZipFile);

枚举ZIP文件本身的时间戳应该无关紧要,但请尝试将ZIP条目的上次修改时间设置为常量值:

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

zo.putNextEntry(entry);
有关更多信息,请参阅JavaDoc


更新

如果您输入的内容和顺序相同,以上内容确实可以做到这一点。我查看了
ZipOutputStream
的源代码,在
putNextEntry
方法中发现了以下内容:

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

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

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

我只是想试试

long time = 0;

不要乱动日历实例。

你正在压缩的文件的时间戳有变化吗?嗯,没有。但这让我想到了解压。我正在解压,然后再次解压。可能是我的解压导致了标题不匹配。我会试试。@RobbyCornelissen没有,我试图改变文件的时间戳amp同样,即使我在下面的回答中设置了
ZipEntry
对象的时间,仍然会生成不同的MD5?太棒了,你就是那个人!我注意到还有ZipEntry.setCreationTime、setLastAccessTime和setAccessTime。我没有使用它们,只有setTime(0)。我使用Calendar.getInstance().get(年、月、日)。我相信这是可以的。Robbys的回答似乎起到了作用。@SecretService很高兴你把它整理好了。你是说
.set
?这是定义不好的:它会返回你选择的日期,但会返回当前时间。你首先需要一个
.clear()
。是的,很棘手的事情。我正在做cal.get(int,int,int);我相信这将返回一天的开始。@SecretService我在这个问题或Javadoc中看不到任何东西表明存在三值
。get(int,int,int)
。对不起,我是说set!:)