How can I make my Java-generated zip file identical to a WinZip-generated one -
i have class zipping directory's contents zip file. code i'm using below. problem i'm having zip file generated me cannot read application i'm loading into. however, if unzip zip file that's beingness generated , utilize winzip zip again, file can used. have no command on target application that's loading zip can create file winzip-generated version. i've opened each zip file using winzip detailed diagnostics feature , can see lots of differences in files produced don't understand ones may causing issue. see bottom of question examples.
package com.mycompany.utils; import java.io.bufferedoutputstream; import java.io.file; import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.ioexception; import java.util.arraylist; import java.util.list; import java.util.zip.zipentry; import java.util.zip.zipoutputstream; import org.apache.log4j.logger; public class filezipper { private static final logger logger = logger.getlogger(filezipper.class); private string destinationzipfile; private string sourcedirectory; list<string> filelist; private file zipfile; public file getzipfile() { homecoming zipfile; } /** * zips source directory destination zip file * * @param source * @param destination */ filezipper(string source, string destination) { logger.info("zipping source directory: "+source); logger.info("to destination zip file: "+destination); this.destinationzipfile = destination; this.sourcedirectory = source; filelist = new arraylist<string>(); generatefilelist(new file(sourcedirectory)); compressdirectorycontentstozip(sourcedirectory, destinationzipfile); } /** * traverse directory , files, , add together file filelist * * @param node * file or directory */ public void generatefilelist(file node) { // add together file if (node.isfile()) { filelist.add(generatezipentry(node.getabsolutefile().tostring())); } if (node.isdirectory()) { if(node.tostring() != sourcedirectory) { filelist.add(generatezipentry(node.getabsolutefile().tostring())); } string[] subnodes = node.list(); (string filename : subnodes) { generatefilelist(new file(node, filename)); } } } /** * compress directory zip file * @param sourcedirectory * @param destinationzipfile */ public void compressdirectorycontentstozip(string sourcedirectory, string destinationzipfile) { this.zipfile = new file(destinationzipfile); byte[] buffer = new byte[4096]; seek { fileoutputstream fos = new fileoutputstream(destinationzipfile); bufferedoutputstream bos = new bufferedoutputstream(fos); zipoutputstream zos = new zipoutputstream(bos); zos.setmethod(zipoutputstream.deflated); logger.info("zipping : " + destinationzipfile); (string entry : this.filelist) { long filesizeinbytes = new file(sourcedirectory + file.separator + entry).length(); if(new file(sourcedirectory + file.separator + entry).isfile()) { logger.info("file added : " + entry + " ("+string.valueof(filesizeinbytes)+" bytes)"); zipentry ze = new zipentry(entry); zos.putnextentry(ze); fileinputstream in = new fileinputstream(sourcedirectory + file.separator + entry); int len; while ((len = in.read(buffer)) > 0) { zos.write(buffer, 0, len); } in.close(); zos.closeentry(); } else if(new file(sourcedirectory + file.separator + entry).isdirectory()) { logger.info("directory added : " + entry); zipentry ze = new zipentry(entry+file.separator); zos.putnextentry(ze); zos.closeentry(); } else { logger.warn("not file or directory: "+entry); } } zos.closeentry(); zos.close(); logger.info("zipping completed successfully"); } grab (ioexception ex) { logger.error(ex); system.exit(1); } logger.info("generated zip file: "+ destinationzipfile); } /** * format filename archiving removing path * of source directory * * @param file * @return */ private string generatezipentry(string file) { logger.debug("stripping '"+file+"' '" +file.substring(sourcedirectory.length() + 1, file.length())+"'"); homecoming file.substring(sourcedirectory.length() + 1, file.length()); } }
so output see in resulting zip file diagnostics in winzip follows:
non-working file class="lang-none prettyprint-override">archive: c:\users\conor\desktop\dp-export-2\dp-export-2.zip 3573 bytes 2014-11-04 20:03:22 current location part 1 offset 3551 end central directory record pk0506 (4+18) ========================================== location of end-of-central-dir record: 3551 (0x00000ddf) bytes part number of part (0000): 1 part number of start of central dir (0000): 1 number of entries in central dir in part: 1 total number of entries in central dir: 1 size of central dir: 56 (0x00000038) bytes relative offset of central dir: 3495 (0x00000da7) bytes zipfile comment length: 0 current location part 1 offset 3495 central directory entry pk0102 (4+42): #1 ====================================== part number in file begins (0000): 1 relative offset of local header: 0 (0x00000000) bytes version made operating scheme (00): ms-dos, os/2, nt fat version made zip software (20): 2.0 operat. scheme version needed extract (00): ms-dos, os/2, nt fat unzip software version needed extract (20): 2.0 general purpose bit flag (0x0808) (bit 15..0): 0000.1000 0000.1000 file security status (bit 0): not encrypted extended local header (bit 3): yes utf-8 names (bit 11): yes compression method (08): deflated compression sub-type (deflation): normal file lastly modified on (0x00004564 0x0000a06a): 2014-11-04 20:03:20 32-bit crc value: 0x07d797c8 compressed size: 3439 bytes uncompressed size: 24021 bytes length of filename: 10 characters length of field: 0 bytes length of file comment: 0 characters internal file attributes: 0x0000 apparent file type: binary external file attributes: 0x00000000 non-msdos external file attributes: 0x000000 ms-dos file attributes (0x00): none filename: export.xml current location part 1 offset 0 local directory entry pk0304 (4+26): #1 ------------------------------------ operat. scheme version needed extract (00): ms-dos, os/2, nt fat unzip software version needed extract (20): 2.0 general purpose bit flag (0x0808) (bit 15..0): 0000.1000 0000.1000 file security status (bit 0): not encrypted extended local header (bit 3): yes utf-8 names (bit 11): yes compression method (08): deflated compression sub-type (deflation): normal file lastly modified on (0x00004564 0x0000a06a): 2014-11-04 20:03:20 32-bit crc value: 0x00000000 compressed size: 0 bytes uncompressed size: 0 bytes note: "real" crc , sizes in extended local header length of filename: 10 characters length of field: 0 bytes filename: export.xml testing export.xml ok current location part 1 offset 3479 extended local dir entry pk0708 (4+12): #1 --------------------------------------- 32-bit crc value: 0x07d797c8 compressed size: 3439 bytes uncompressed size: 24021 bytes no errors detected in compressed info of c:\users\conor\desktop\dp-export-2\dp-export-2.zip.
working file re-zipped unzip of non-working file class="lang-none prettyprint-override">archive: c:\users\conor\desktop\dp-export-2\dp-export-2b.zip 3564 bytes 2014-11-04 20:04:46 current location part 1 offset 3542 end central directory record pk0506 (4+18) ========================================== location of end-of-central-dir record: 3542 (0x00000dd6) bytes part number of part (0000): 1 part number of start of central dir (0000): 1 number of entries in central dir in part: 1 total number of entries in central dir: 1 size of central dir: 92 (0x0000005c) bytes relative offset of central dir: 3450 (0x00000d7a) bytes zipfile comment length: 0 current location part 1 offset 3450 central directory entry pk0102 (4+42): #1 ====================================== part number in file begins (0000): 1 relative offset of local header: 0 (0x00000000) bytes version made operating scheme (00): ms-dos, os/2, nt fat version made zip software (20): 2.0 operat. scheme version needed extract (00): ms-dos, os/2, nt fat unzip software version needed extract (20): 2.0 general purpose bit flag (0x0002) (bit 15..0): 0000.0000 0000.0010 file security status (bit 0): not encrypted extended local header (bit 3): no compression method (08): deflated compression sub-type (deflation): maximum file lastly modified on (0x00004564 0x0000a06a): 2014-11-04 20:03:20 32-bit crc value: 0x07d797c8 compressed size: 3410 bytes uncompressed size: 24021 bytes length of filename: 10 characters length of field: 36 bytes length of file comment: 0 characters internal file attributes: 0x0001 apparent file type: text external file attributes: 0x00000020 non-msdos external file attributes: 0x000000 ms-dos file attributes (0x20): arc filename: export.xml field 0x000a (pkware win32 filetimes), 4 header , 32 info bytes: extended timestamps are: creation date: 2014-11-04 20:03:20 lastly modified date: 2014-11-04 20:03:20 lastly accessed date: 2014-11-04 20:03:20 current location part 1 offset 0 local directory entry pk0304 (4+26): #1 ------------------------------------ operat. scheme version needed extract (00): ms-dos, os/2, nt fat unzip software version needed extract (20): 2.0 general purpose bit flag (0x0002) (bit 15..0): 0000.0000 0000.0010 file security status (bit 0): not encrypted extended local header (bit 3): no compression method (08): deflated compression sub-type (deflation): maximum file lastly modified on (0x00004564 0x0000a06a): 2014-11-04 20:03:20 32-bit crc value: 0x07d797c8 compressed size: 3410 bytes uncompressed size: 24021 bytes length of filename: 10 characters length of field: 0 bytes filename: export.xml testing export.xml ok no errors detected in compressed info of c:\users\conor\desktop\dp-export-2\dp-export-2b.zip.
so can see differences here in outputs don't understand why differences there, nor know 1 cause of failure. help in identifying why java-generated file might not liked target application great help. have inkling cause way crc calculated java vs winzip , subsequently added archive, have no experience of kind of issue. other theory it's due internal file attributes. illustration that's failing parsed shows 'export.xml' binary info winzip version shows text.
i worked around issue, don't understand root cause using org.apache.commons.compress library zip file usable. i'll dig 1 time again tomorrow because i'm curious know difference is. meanwhile, here's updated class.
package com.mycompany.utils; import java.io.bufferedoutputstream; import java.io.file; import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.ioexception; import java.util.arraylist; import java.util.list; import org.apache.commons.compress.archivers.zip.ziparchiveentry; import org.apache.commons.compress.archivers.zip.ziparchiveoutputstream; import org.apache.log4j.logger; public class filezipper { private static final logger logger = logger.getlogger(oldfilezipper.class); private string destinationzipfile; private string sourcedirectory; list<string> filelist; private file zipfile; public file getzipfile() { homecoming zipfile; } /** * zips source directory destination zip file * * @param source * @param destination */ filezipper(string source, string destination) { logger.info("zipping source directory: "+source); logger.info("to destination zip file: "+destination); this.destinationzipfile = destination; this.sourcedirectory = source; filelist = new arraylist<string>(); generatefilelist(new file(sourcedirectory)); compressdirectorycontentstozip(sourcedirectory, destinationzipfile); } /** * traverse directory , files, , add together file filelist * * @param node * file or directory */ public void generatefilelist(file node) { // add together file if (node.isfile()) { filelist.add(generatezipentry(node.getabsolutefile().tostring())); } if (node.isdirectory()) { if(node.tostring() != sourcedirectory) { filelist.add(generatezipentry(node.getabsolutefile().tostring())); } string[] subnodes = node.list(); (string filename : subnodes) { generatefilelist(new file(node, filename)); } } } /** * compress directory zip file * @param sourcedirectory * @param destinationzipfile */ public void compressdirectorycontentstozip(string sourcedirectory, string destinationzipfile) { this.zipfile = new file(destinationzipfile); byte[] buffer = new byte[4096]; seek { fileoutputstream fos = new fileoutputstream(destinationzipfile); bufferedoutputstream bos = new bufferedoutputstream(fos); ziparchiveoutputstream zos = new ziparchiveoutputstream(bos); zos.setmethod(ziparchiveoutputstream.deflated); zos.setlevel(0); logger.info("zipping : " + destinationzipfile); (string entry : this.filelist) { long filesizeinbytes = new file(sourcedirectory + file.separator + entry).length(); if(new file(sourcedirectory + file.separator + entry).isfile()) { logger.info("file added : " + entry + " ("+string.valueof(filesizeinbytes)+" bytes)"); ziparchiveentry ze = new ziparchiveentry(entry); zos.putarchiveentry(ze); fileinputstream in = new fileinputstream(sourcedirectory + file.separator + entry); int len; while ((len = in.read(buffer)) > 0) { zos.write(buffer, 0, len); } in.close(); zos.closearchiveentry(); } else if(new file(sourcedirectory + file.separator + entry).isdirectory()) { logger.info("directory added : " + entry); ziparchiveentry ze = new ziparchiveentry(entry+file.separator); zos.putarchiveentry(ze); zos.closearchiveentry(); } else { logger.warn("not file or directory: "+entry); } } zos.close(); logger.info("zipping completed successfully"); } grab (ioexception ex) { logger.error(ex); system.exit(1); } logger.info("generated zip file: "+ destinationzipfile); } /** * format filename archiving removing path * of source directory * * @param file * @return */ private string generatezipentry(string file) { logger.debug("stripping '"+file+"' '"+file.substring(sourcedirectory.length() + 1, file.length())+"'"); homecoming file.substring(sourcedirectory.length() + 1, file.length()); } }
java zip
No comments:
Post a Comment