I have this, which works fine for zipping and unzipping:
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();
}
}
However, the zip file will have a different checksum even though the content of the file is unchanged. This is a problem when committing the files using git.
How can I ensure that the zipped file stays the same every time unless content has changed?
The timestamp on the ZIP file itself shouldn't matter, but try setting the last modification time of the ZIP entries to a constant value:
ZipEntry entry = new ZipEntry(path);
entry.setTime(0);
zo.putNextEntry(entry);
See the setTime
JavaDoc for more info.
Update
The above should indeed do the trick, provided the content and order of your entries is identical. I took a look at the source code for ZipOutputStream
, and found the following in the putNextEntry
method:
if (e.time == -1) {
e.setTime(System.currentTimeMillis());
}
So setting the time
to 0 before adding the entry to the stream should prevent it from being overwritten, and keep your content constant.
I'm not certain what your Cal
class is doing, but I suspect that internally it's creating a Calendar
instance and setting the date fields. You should be aware that if you do this then it will still end up with the current time of day, not 00:00! So you are most likely not getting the same timestamp each time.
I'd just try
long time = 0;
rather than mucking about with calendar instances.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.