我有这个,它适用于压缩和解压缩:
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提交文件时出现问题。
除非内容发生变化,否则我怎样才能确保每次压缩文件保持不变?
答案 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;
而不是与日历实例混淆。