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!:)