KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > yagga > util > Unzip


1 /*
2  * This file is part of MiniInstaller, a self installer builder for Java
3  * Copyright (C) 2002 Walter Gamba
4  * mailto:walter@yagga.net
5  * http://www.yagga.net/java/miniinstaller
6  *
7  * MiniInstaller is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * MiniInstaller is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * As the time of writing, the GNU General Public Licene can be
22  * found at http://www.gnu.org/licenses/gpl.txt
23  *
24  */

25
26 package net.yagga.util;
27
28 import java.io.*;
29 import java.util.zip.*;
30 import java.util.*;
31
32 /**
33  * Unzipper class. It unzipz standrd ZIP files as well as Jar files.
34  * It was a hell of a code writing...<BR>
35  * THe typical usage is as follows..
36  * <CODE>
37  * Unzip u=new Unzip("archive.zip","/usr/tmp");<BR>
38  * u.uncompress(false); //verbose set to false..<BR>
39  * </CODE><BR>
40  * Or..if we want to trAck esxtraction..<BR>
41  * <CODE>
42  * while((ret=u.chunkuncompress(false,true,true))!=-1){<BR>
43  * System.out.println(ret);<BR>
44  * }<BR>
45  * </CODE>
46  *
47  * @author Walter Gamba
48  * @version 1.0
49  */

50 public class Unzip {
51
52     /**
53      * Store here extracted files..
54      */

55     private Vector extractedFiles;
56     private Vector createdDirs;
57
58   public static void main(String JavaDoc argv[]){
59     Unzip u=new Unzip(argv[0],argv[1]);
60     //u.listFiles();
61
//u.uncompress(false);
62
//do progress uncompress...
63
int ret;
64     int acc=0;
65     int sg=3;
66     while((ret=u.chunkuncompress(false,true,true))!=-1){
67       acc=ret;
68       if(acc>=sg){
69         System.out.print(".");
70         sg+=3;
71       }
72     }
73   }
74
75     /**
76      * @return a Vector of File containing extracted files.
77      */

78     public Vector getExtractedFilesList(){
79         return extractedFiles;
80     }
81     /**
82      * @return a Vector of File containing created directories.
83      */

84     public Vector getCreatedDirsList(){
85         return createdDirs ;
86     }
87
88   String JavaDoc zipFile;
89   String JavaDoc destDir;
90   //for chunking
91
long maxSize=0;
92   long currSize=0;
93
94   public Unzip(String JavaDoc zFile, String JavaDoc dDir) {
95     zipFile=zFile;
96         extractedFiles=new Vector();
97         createdDirs=new Vector();
98     destDir=dDir;
99     getStats2();
100     startChunking();
101   }
102
103   public long getMax(){
104     return maxSize;
105   }
106
107   private void getStats(){
108
109     ZipFile zip=null;
110     try{
111       zip=new ZipFile(zipFile);
112       Enumeration e=zip.entries();
113       while(e.hasMoreElements()){
114         ZipEntry ze=(ZipEntry)e.nextElement();
115         maxSize+=ze.getSize();
116       }
117       //Ut.infoln("Size="+maxSize);
118
zip.close();
119     }catch(IOException ioe){
120       Ut.error("Error reading zip file '"+zipFile+"':"+ioe);
121       System.exit(0);
122     }
123
124   }
125
126   private void getStats2(){
127     ZipInputStream zis=getZIS();
128     try{
129       ZipEntry ze=null;
130       while((ze=zis.getNextEntry())!=null){
131         maxSize+=ze.getSize();
132       }
133       //Ut.infoln("Size="+maxSize);
134
zis.close();
135     }
136     catch(ZipException ze){
137       Ut.error("Error reading Zip file '"+zipFile+"':"+ze);
138       System.exit(0);
139     }
140     catch(IOException ioe){
141       Ut.error("Error reading zip file '"+zipFile+"':"+ioe);
142       System.exit(0);
143     }
144
145   }
146
147   public void startChunking(){
148     currSize=0;
149   }
150   /*
151   public void listFiles(){
152     ZipFile zip=null;
153     try{
154       zip=new ZipFile(zipFile);
155     Enumeration e=zip.entries();
156     while(e.hasMoreElements()){
157       ZipEntry ze=(ZipEntry)e.nextElement();
158       //System.out.println(ze+"["+ze.getName()+"]");
159       if(ze.getName().equals("bin/test.conf"))
160         unpack(zip,ze);
161       //zip.close();
162     }
163     }catch(IOException ioe){
164       Ut.error("Error reading zip file '"+zipFile+"':"+ioe);
165       System.exit(0);
166     }
167   }
168   */

169   public void uncompress(ZipEntry _ze, boolean verbose){
170     ZipInputStream zis=getZIS();
171     ZipEntry ze=null;
172     try{
173     while ((ze=zis.getNextEntry())!=null) {
174        if (ze==_ze) {
175              int size=(int)ze.getSize();
176              // -1 means unknown size.
177
if (size==-1) {
178                 Ut.error("Unknown size for "+ze);
179                 return;
180              }
181              byte[] b=new byte[(int)size];
182              int rb=0;
183              int chunk=0;
184              while (((int)size - rb) > 0) {
185                  chunk=zis.read(b,rb,(int)size - rb);
186                  if (chunk==-1) {
187                     break;
188                  }
189                  rb+=chunk;
190              }
191              // add to internal resource hashtable
192
//writes files
193
writeUncompressedFile(ze,b,verbose);
194
195         return;
196        }
197     }
198     }
199     catch(IOException ioe){
200       Ut.error(" decompressing "+ze+":"+ioe);
201     }
202   }
203
204     /**
205      * Use this to uncompress in a straight way a ZIP/JAR file
206      * @param verbose print progress informations
207      */

208   public void uncompress(boolean verbose){
209       try {
210           // extract resources and put them into the hashtable.
211
/* FileInputStream fis=new FileInputStream(zipFile);
212           BufferedInputStream bis=new BufferedInputStream(fis);
213           */

214           ZipInputStream zis=getZIS();
215           ZipEntry ze=null;
216           while ((ze=zis.getNextEntry())!=null) {
217              if (ze.isDirectory()) {
218                 continue;
219              }
220
221              int size=(int)ze.getSize();
222              // -1 means unknown size.
223
if (size==-1) {
224                 Ut.error("Unknown size for "+ze);
225                 return;
226              }
227              byte[] b=new byte[(int)size];
228              int rb=0;
229              int chunk=0;
230              while (((int)size - rb) > 0) {
231                  chunk=zis.read(b,rb,(int)size - rb);
232                  if (chunk==-1) {
233                     break;
234                  }
235                  rb+=chunk;
236              }
237              // add to internal resource hashtable
238
//writes files
239
writeUncompressedFile(ze,b,verbose);
240           }
241        } catch (NullPointerException JavaDoc e) {
242           Ut.error("zip: done.");
243        } catch (FileNotFoundException e) {
244           e.printStackTrace();
245        } catch (IOException e) {
246           e.printStackTrace();
247        }
248   }
249
250   private ZipInputStream getZIS(){
251     InputStream is=ResourceMgr.openResource(zipFile);
252     return new ZipInputStream(is);
253   }
254   /**
255     chunked
256   */

257   ZipInputStream chunkzis=null;
258
259     /**
260      * Uncompress file chunked.. so to get track of the progress of the unzipping process
261      * @param verbose display progress info
262      * @param acc add size extracted to last size returned..
263      * @param percent transform progress values to percent values (if true) or get raw data
264      * ifa false
265      * @return return the size of extracted data in bytes.. if percent is true return a percentage
266      * returns -1 if there is an error.
267      */

268   public int chunkuncompress(boolean verbose, boolean acc, boolean percent){
269         try {
270             // extract resources and put them into the hashtable.
271
if(chunkzis==null){
272               chunkzis=getZIS();
273             }
274             ZipEntry ze=null;
275             //while ((ze=chunkzis.getNextEntry())!=null) {
276
if((ze=chunkzis.getNextEntry())!=null) {
277               if (ze.isDirectory()) {
278                     if(acc){
279                       if(percent)
280                             return (int)(currSize*100.0f/(float)maxSize);
281                       else
282                             return (int)currSize;
283                     }
284                     return 0;
285               }
286
287               int size=(int)ze.getSize();
288             // -1 means unknown size.
289
if (size==-1) {
290                     Ut.error("Unknown size for "+ze);
291                     return -1;
292               }
293                 byte[] b=new byte[(int)size];
294                 int rb=0;
295                 int chunk=0;
296                 while (((int)size - rb) > 0) {
297                   chunk=chunkzis.read(b,rb,(int)size - rb);
298                     if (chunk==-1) {
299                       break;
300                     }
301                     rb+=chunk;
302               }
303                 // add to internal resource hashtable
304
//writes files
305
writeUncompressedFile(ze,b,verbose);
306                 if(acc)
307                 {
308                   currSize+=size;
309                     if(percent){
310                         float perc=(currSize*100.0f/(float)maxSize);
311                         //Ut.infoln("size is "+size+", currSize is"+currSize+", perc="+perc);
312
return (int)perc;
313                   }
314                   else
315                         return (int)currSize;
316               }
317               else{
318                     if(percent)
319                       return (int)((float)size*100.0f/maxSize);
320                     else
321                       return size;
322               }
323             }//if getNextEntry..
324
} catch (NullPointerException JavaDoc e) {
325         Ut.error("zip:done.");
326         } catch (FileNotFoundException e) {
327         e.printStackTrace();
328         } catch (IOException e) {
329         e.printStackTrace();
330         }
331     return -1;
332   }
333
334     /**
335      * Actually write an extracted file to file system. Stores created dirs and files
336      * in vectors> Such vectors can later be retrieved.
337      * @param ze a ZipEntry the file/directory to write
338      * @param buffer
339      * @param verbose
340      */

341   private void writeUncompressedFile(ZipEntry ze, byte[] buffer, boolean verbose){
342     //
343
//builds directory if it does not exists, but skip plain directories...
344
if(ze.isDirectory())
345       return;
346     File f=new File(destDir);
347     File n=new File(f.getAbsolutePath()+File.separator+ze.getName());
348     //ne estraggo il path e lo creo..
349
File dir=n.getParentFile();
350     if(!dir.exists()){
351             //create dir
352
createdDirs.add(dir);
353             if(!dir.mkdirs()){
354                 Ut.error("Error: impossible to create directory(ies)"+dir);
355                 return;
356             }
357     }
358     try{
359             if(Ut.writeBinFile(n.getCanonicalPath(),buffer,true)) {
360         extractedFiles.add(n);
361               if(verbose)
362           Ut.infoln(ze.getName()+"> "+n.getCanonicalPath());
363       }
364       else
365         Ut.error("Error uncompressing/writing to file "+n);
366     }
367     catch(IOException ioe){
368       Ut.error("Error uncompressing/writing to file "+n+":"+ioe);
369     }
370   }
371
372 }
373
374
375
376
Popular Tags