Include my own version for your reference.
We use the this one to zip up photos to download so it works with various unzip programs. It preserves the directory structure and timestamps.
Public Static voidCreatezipfile (File srcdir, outputstream out,BooleanVerbosethrowsIOException {List<String> fileList =listdirectory (Srcdir); Zipoutputstream Zout=NewZipoutputstream (out); Zout.setlevel (9); Zout.setcomment ("Zipper v1.2"); for(String filename:filelist) {File file=NewFile (Srcdir.getparent (), fileName); if(verbose) System.out.println ("Adding:" +fileName); //Zip always use/as separatorString Zipname =FileName; if(File.separatorchar! = '/')) Zipname= Filename.replace (File.separatorchar, '/')); ZipEntry ze; if(File.isfile ()) {ze=NewZipEntry (zipname); Ze.settime (File.lastmodified ()); Zout.putnextentry (Ze); FileInputStream Fin=Newfileinputstream (file); byte[] buffer =New byte[4096]; for(intN (n = fin.read (buffer)) > 0;) zout.write (buffer,0, N); Fin.close (); } Else{ze=NewZipEntry (Zipname + '/')); Ze.settime (File.lastmodified ()); Zout.putnextentry (Ze); }} zout.close (); } Public StaticList<string>listdirectory (File directory)throwsIOException {Stack<String> stack =NewStack<string>(); List<String> list =NewArraylist<string>(); //If It ' s a file, just return itself if(Directory.isfile ()) {if(Directory.canread ()) List.add (Directory.getname ()); returnlist; } //Traverse the directory in Width-first manner, no-recursivelyString root =directory.getparent (); Stack.push (Directory.getname ()); while(!Stack.empty ()) {String current=(String) Stack.pop (); File CurDir=NewFile (root, current); String[] FileList=curdir.list (); if(FileList! =NULL) { for(String entry:filelist) {File F=NewFile (CurDir, entry); if(F.isfile ()) {if(F.canread ()) {List.add (current+ File.separator +entry); } Else{System.err.println ("File" +F.getpath ()+ "is unreadable"); Throw NewIOException ("Can ' t Read file:" +F.getpath ()); } } Else if(F.isdirectory ()) {List.add (current+ File.separator +entry); Stack.push ( current+ File.separator +f.getname ()); } Else { Throw NewIOException ("Unknown entry:" +F.getpath ()); } } } } returnlist;}}
SEPARATOR constant is initialised with the System.getproperty ("File.separator") which would give me the OS default file Sep Arator.
I would never hardcode a separator since that assumes that your code would only being deployed on a given OS
Don ' t use the file.separator in ZIP. The separator must is "/" according to the spec. If you is on Windows, you must open file as "D:\dir\subdir\file" but ZIP entry must is "Dir/subdir/file"
Just go through the source of Java.util.zip.ZipEntry. It treats a zipentry as directory if its name is ends with "/" characters. Just suffix the directory name with "/". Also need to remove the drive prefix to make it relative.
Here's another example (recursive) which also lets you include/exclude the containing folder form the Zip:
ImportJava.io.File;ImportJava.io.FileInputStream;ImportJava.io.FileOutputStream;Importjava.io.IOException;ImportJava.util.zip.ZipEntry;ImportJava.util.zip.ZipOutputStream; Public classZiputil {Private Static Final intDefault_buffer_size = 1024 * 4; Public Static voidMain (string[] args)throwsException {zipfile ("C:/tmp/demo", "C:/tmp/demo.zip",true); } Public Static voidZipFile (String filetozip, String ZipFile,BooleanExcludecontainingfolder)throwsIOException {zipoutputstream zipout=NewZipoutputstream (NewFileOutputStream (ZipFile)); File Srcfile=NewFile (Filetozip); if(Excludecontainingfolder &&srcfile.isdirectory ()) { for(String fileName:srcFile.list ()) {Addtozip ("", Filetozip + "/" +FileName, zipout); } } Else{addtozip ("", Filetozip, zipout); } zipout.flush (); Zipout.close (); System.out.println ("Successfully created" +ZipFile); } Private Static voidaddtozip (string path, String srcfile, Zipoutputstream zipout)throwsIOException {File file=NewFile (srcfile); String FilePath= "". Equals (Path)? File.getname (): Path + "/" +File.getname (); if(File.isdirectory ()) { for(String fileName:file.list ()) {Addtozip (FilePath, Srcfile+ "/" +FileName, zipout); } } Else{zipout.putnextentry (NewZipEntry (FilePath)); FileInputStream in=NewFileInputStream (srcfile); byte[] buffer =New byte[Default_buffer_size]; intLen; while(len = in.read (buffer))! =-1) {zipout.write (buffer,0, Len); } in.close (); } }}
Http://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure
Java.util.zip-recreating directory Structure (EXT)