Erro ao descompactar arquivos .zip com Java

Olá a todos,

Estou com um problema para descompactar arquivos .zip que possuem subpastas.

Se eu coloco todos os arquivos na raiz do zip, o erro não acontece, mas se eu coloco algum dentro de alguma pasta ele não o encontra.

O erro apresentado é o seguinte:

java.io.FileNotFoundException: fotos\foto1.htm (O sistema não pode encontrar o caminho especificado)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.(FileOutputStream.java:179)
at java.io.FileOutputStream.(FileOutputStream.java:70)
at servico.main.MainServico.main(MainServico.java:36)

e o codigo que eu escrevi é o seguinte:

public class Zip{
   static final int BUFFER = 2048;
   public static void main (String argv[]) {
      try {
         BufferedOutputStream dest = null;
         BufferedInputStream is = null;
         ZipEntry entry;
         ZipFile zipfile = new ZipFile("c:\\zip\\arquivo.zip");
         Enumeration e = zipfile.entries();
         while(e.hasMoreElements()) {
            entry = (ZipEntry) e.nextElement();
            System.out.println("Extracting: " +entry);
            is = new BufferedInputStream (zipfile.getInputStream(entry));
            int count;
            byte data[] = new byte[BUFFER];
            FileOutputStream fos = new FileOutputStream(entry.getName());
            dest = new BufferedOutputStream(fos, BUFFER);
            while ((count = is.read(data, 0, BUFFER)) != -1) {
               dest.write(data, 0, count);
            }
            dest.flush();
            dest.close();
            is.close();
         }
      } catch(Exception e) {
         e.printStackTrace();
      }
   }
}

Desde já agradeço pela atenção!!

Eu creio que você precisa informar o caminho completo do arquivo que será extraído, mas acho isso varia de acordo com a forma que você “zipou”…

Substitua:

FileOutputStream fos = new FileOutputStream(entry.getName()); 

Por:

String ls_outputfile =  entry.getName().substring(entry.getName().lastIndexOf(File.separator)+1, entry.getName().length() );
ls_output    =   System.getProperty( "user.dir" ).toString()+File.separator+"Data"+File.separator+ls_outputfile;
FileOutputStream fos = new FileOutputStream(ls_output);

Espero que ajude…

Eu fiz umas modificacoes nesse trecho de codigo q vc me escreveu…

mas eu nao sei se isso está certo… coloquei assim:

            String ls_outputfile =  entry.getName().substring(entry.getName().lastIndexOf(File.separator)+1, entry.getName().length() );  
            ls_outputfile    =   "c:"+File.separator+"zip"+File.separator+"arquivo"+File.separator+ls_outputfile;  
            FileOutputStream fos = new FileOutputStream(ls_outputfile); 

ai o caminho q ele gera nessa variavel eh c:\zip\arquivo\index.html

e diz q nao foi possivel encontrar…
essa variavel nao eh o local de destino, onde irao ficar os arquivos ??

Um problema que já tive ao extrair arquivos .zip é que você precisa criar os subdiretórios antes de criar os arquivos, caso não existam.

“new FileOutputStream” só cria um arquivo, não cria os subdiretórios necessários.

Não rodei seu programa, mas acredito que esse é um dos problemas que você vai encontrar.

Depois de ler as repostas cheguei ao seguinte código…

Está funcionando por aqui… Estou colocando ele só como solução para o problema. Não sei se é o modo mais performático, mas funciona hehe

public class Unzip{
   static final int BUFFER = 2048;
   public static void main (String argv[]) {
      try {
         BufferedOutputStream dest = null;
         BufferedInputStream is = null;
         ZipEntry entry;
         ZipFile zipfile = new ZipFile("c:\\zip\\arquivo.zip");
         Enumeration e = zipfile.entries();

         File f = null;
         
         Timestamp t = new Timestamp(new Date().getTime());
         int time = t.getNanos();
         File pasta = new File("c:\\zip\\pasta_"+time);
         boolean criou = pasta.mkdir(); 
         criou = pasta.setWritable(true);
         while(e.hasMoreElements()) {
            entry = (ZipEntry) e.nextElement();
            
            if(entry.isDirectory()){
                continue;
            }
            
            // verificando se o entry possui pasta
            String vet[] = entry.getName().split("/");
            String subpasta = "";
            if( vet.length > 1 ) {
                // cria qtas pastas estiverem no entry
                for(int i = 0 ; i < vet.length-1 ; i ++){
                    f = new File("c:\\zip\\pasta_"+time+"\\"+vet[i]);
                    criou = f.mkdir();
                    f.setWritable(true);
                    subpasta += f.getName()+File.separator;
                }
            }
            
            System.out.println("Extracting: " +entry);
            is = new BufferedInputStream (zipfile.getInputStream(entry));
            int count;
            byte data[] = new byte[BUFFER];
            
            
            String ls_outputfile =  entry.getName().substring(entry.getName().lastIndexOf(File.separator)+1, entry.getName().length() );
            ls_outputfile    =   "c:"+File.separator+"zip"+File.separator+pasta.getName()+File.separator+ls_outputfile;            
            
            FileOutputStream fos = new FileOutputStream(ls_outputfile);
            
            dest = new BufferedOutputStream(fos);
            while ((count = is.read(data, 0, BUFFER)) != -1) {
               dest.write(data, 0, count);
            }
            dest.flush();
            dest.close();
            is.close();
         }
      } catch(Exception e) {
         e.printStackTrace();
      }
   }
    
}

Valeu a ajuda de todos!!

=D