2013-06-11 29 views
6

Sto chiudendo il contenuto di una directory, ma sto incontrando un errore quando provo ad aprire i file compressi.Java util zip crea file zip "corrotti"

Qualcuno può dire cosa sta succedendo con il mio codice? Forse non sto assegnando abbastanza byte?

Guardare all'interno di zipDirectory() e vedrete che sto facendo zip su cartelle che contengono file di estensione speciali.

Non so dove si sta verificando l'errore, quindi forse qualcuno può aiutarmi!

molto apprezzato

private void zipDirectory() { 

     File lazyDirectory = new File(defaultSaveLocation); 

     File[] files = lazyDirectory.listFiles(); 

     for (File file : files) { 

      if (file.isDirectory()) { 
      System.out.println("Zipping up " + file); 
      zipContents(file); 
      } 
     }  
    } 


public static void addToZip(String fileName, ZipOutputStream zos) throws FileNotFoundException, IOException { 

    System.out.println("Writing '" + fileName + "' to zip file"); 

    File file = new File(fileName); 
    FileInputStream fis = new FileInputStream(file); 
    ZipEntry zipEntry = new ZipEntry(fileName); 
    zos.putNextEntry(zipEntry); 

    byte[] bytes = new byte[1024]; 
    int length; 
    while ((length = fis.read(bytes)) >= 0) { 
     zos.write(bytes, 0, length); 
    } 

    zos.closeEntry(); 
    fis.close(); 

    } 

public static void zipContents(File dirToZip) { 

    List<File> fileList = new ArrayList<File>(); 

    File[] filesToZip = dirToZip.listFiles(); 

    for (File zipThis : filesToZip) { 

     String ext = ""; 

     int i = zipThis.toString().lastIndexOf('.'); 

     if (i > 0) { 
      ext = zipThis.toString().substring(i+1); 
     } 

     if(ext.matches("cpp|bem|gz|h|hpp|pl|pln|ppcout|vec|xml|csv")){ 
      fileList.add(zipThis); 
     } 

    } 


    try { 
     FileOutputStream fos = new FileOutputStream(dirToZip.getName() + ".zip"); 
     ZipOutputStream zos = new ZipOutputStream(fos); 

     for (File file : fileList) { 

      addToZip(file.toString(), zos); 

     } 

     } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } catch (IOException e) { 
     e.printStackTrace(); 
    } 

enter image description here

+2

Non dovresti eseguire zos.close() dopo l'ultimo per? – Piovezan

+1

Sarei anche preoccupato per questo: 'file.toString()'. Questo dice aggiungere il file "C: \ some \ dir \ some \ where \ file.ext" al file zip, usando quel percorso. Ciò significa che quando si arriva a decomprimerlo, verrà decompresso in questa posizione ESATTA. Meglio provare a costruire un percorso relativo basato sul percorso di primo livello originale (cioè, tagliare il genitore di radice;)) – MadProgrammer

+0

Non sono mai riuscito a farlo funzionare con gli util java standard. L'eliminazione di Apache Commons Compress (e l'aggiunta di alcune chiamate di chiusura archivio) ha risolto questo problema per me. Inoltre, assicurati di avvolgere i flussi di input/output nei lettori/scrittori bufferizzati. – Amalgovinus

risposta

14

Come la maggior parte dei problemi con IO flussi in Java, colpa tua è quasi certamente che non si sta chiudendo i flussi in modo corretto. È necessario aggiungere:

zos.finish(); // good practice 
zos.close(); 

dopo il ciclo for.

+0

forse vuoi dire "flush". Ad ogni modo, voto per il commento di Pioevezan. – SJuan76

+2

No, intendo 'finish()'. Nel caso di ZipOutputStream, finish() è diverso da flush(). – rolfl

+0

ok ora capisco, grazie. – SJuan76

0

Per me la correzione è che avete bisogno di fare questo per Ogni voce file di

zos.finish() 
zos.flush() 
zos.closeEntry() 

Poi fare le cose di cui sopra di nuovo per chiudere la zos. In caso contrario, la finestra predefinita non può aprire correttamente la cartella zippata, ma l'applicazione di terze parti funziona.

0

Questo può accadere anche se si utilizza uno scrittore character-oriented (es FileWriter) per creare i file decompressi (che in realtà contengono i dati binari)

ero in grado di leggere i file che ero l'estrazione e il passaggio ad un flusso di output binario (FileOutputStream) risolto il problema