2013-06-07 10 views
5

Ich stehe vor einem ungewöhnlichen Problem. Ich baue ein Tool, das alle 5 Minuten ausgeführt werden soll. Es wird die Zip-Dateien aus einem bestimmten Verzeichnis abholen und Dateien (abhängig vom Dateinamen) zu einem Ziel extrahieren. Ich benutze zipentry, um jeden Dateinamen in zip-Datei zu erhalten und dann extrahieren, wie erforderlich, dann ich sie zurück (Zip-Dateien, sobald ich alle Dateien in einer Zip) zu einem bestimmten Verzeichnis und löschen Sie dann die Zip-Datei. Aber manchmal (nicht immer) werden die Zip-Dateien nicht gelöscht. Da verwende ich fileutils.forcedelete(). Ich erhalte eine Ausnahme: kann die Datei nicht löschen. Also habe ich den Code geändert, um fileutils.forcedeleteonexit() noch einige Dateien in der Quelle zu verwenden. HierKann die ZIP-Datei nach dem Entpacken nicht löschen?

ist eine Probe von meinem Code:

sourceFile=new file(zipfile); 
zipFile = new ZipFile(sourceFile); 
zEnum = (Enumeration<ZipEntry>) zipFile.entries(); 
for (int a = 0; a < zipFile.size(); a++) 
{ 
    ZipEntry zE = zEnum.nextElement(); 
    //Function uses zip4j for extracting. No streams used. 
    extract(String sourceZipFile, String fileNameToExtract, String outputFolder); 
} 
//I tried it with finally either 
zipFile.close(); 

//Using fileutils to copy. No streams used. 
copyFile(sourceFile, backup); 

FileUtils.forceDeleteOnExit(sourceFile); 

Es gibt keine Ströme verwendet, aber ich erhalte eine Sperre auf Dateien manchmal (nicht immer). Was scheint hier der Fehler zu sein? Ist es die Extraktion von zip4j, die das Problem oder etwas anderes verursacht? Ich benutze zip4j 1.3.1.

+3

Was O? Windows hat notorische Probleme mit Dateigriffen und Löschungen ... – fge

+0

@fge: Windows.tried in meinem lokalen und auf einem Server (Windows Server 2008 R2) –

+0

@fge Ich kann nicht sagen, wie oft Windows mir gesagt hat "file in Verwenden Sie "wenn Sie versuchen, ein Archiv nach dem Extrahieren seiner Daten zu löschen, aber es war sicherlich öfter, als ich auf beiden Händen zählen kann. Ist es der Fehler von Programmen, die ihre Datei-Handles nicht ordnungsgemäß schließen, oder hält Windows bestimmte Dateien auch nach dem Schließen von Programmen geöffnet? – JAB

Antwort

0

Verwenden Sie Apache-Commons IO's FileDeleteStrategy. Etwas wie:

FileDeleteStrategy.FORCE.delete(file); 

aktualisieren:

sollte es sein, die Art und Weise IO in Ihrer Anwendung behandelt wird. Ich habe einen einfachen Code geschrieben, der eine Zip-Datei in eine temporäre Zip-Datei kopiert, die temporäre Zip-Datei entleert und nach einigen Sekunden löscht. Hier gehts:

public class ZipTest { 

private static String dirPath = "/home/ubuntuuser/Desktop/"; 

public static void main(String[] args) throws Exception { 

    File myzip = new File(dirPath + "content.zip"); 
    String tempFileStr = dirPath + "content_temp.zip"; 
    File tempFile = new File(tempFileStr); 
    String unzipFolderStr = dirPath + "unzip"; 


    copyUsingChannels(myzip, tempFile); 

    // copyUsingStreams(myzip, tempFile); 

    unZip(tempFileStr, unzipFolderStr); 

    Thread.sleep(3000); 

    tempFile.delete(); 


} 

private static void copyUsingStreams(File myzip, File tempFile) 
     throws IOException, FileNotFoundException { 
    byte[] barray = new byte[1024]; 

    if (!tempFile.exists()) 
    { 
     tempFile.createNewFile(); 
    } 

    FileOutputStream fos = new FileOutputStream(tempFile); 
    FileInputStream fis = new FileInputStream(myzip); 

    int length = 0; 

    while ((length = fis.read(barray)) != -1) 
    { 
     fos.write(barray, 0, length); 
    } 

    fis.close(); 
    fos.close(); 
} 

public static void copyUsingChannels(final File srcFile, final File destFile) throws Exception 
{ 
    if (!destFile.exists()) 
    { 
     destFile.createNewFile(); 
    } 

    FileChannel source = new FileInputStream(srcFile).getChannel(); 
    FileChannel destination = new FileOutputStream(destFile).getChannel(); 

    source.transferTo(0, source.size(), destination); 

    source.close(); 
    destination.close(); 
} 

private static void unZip(String zipFile, String outputFolder) throws Exception { 

    byte[] buffer = new byte[1024]; 

    File folder = new File(outputFolder); 
    if (!folder.exists()) { 
     folder.mkdir(); 
    } 

    ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile)); 
    ZipEntry ze = zis.getNextEntry(); 

    while (ze != null) { 

     String fileName = ze.getName(); 

     File newFile = new File(outputFolder + File.separator + fileName); 

     System.out.println("file unzip : " + newFile.getAbsoluteFile()); 

     new File(newFile.getParent()).mkdirs(); 

     if (ze.isDirectory()) 
     { 
      newFile.mkdir(); 
      ze = zis.getNextEntry(); 
      continue; 
     } 

     FileOutputStream fos = new FileOutputStream(newFile); 

     int len; 
     while ((len = zis.read(buffer)) > 0) { 
      fos.write(buffer, 0, len); 
     } 

     fos.close(); 
     ze = zis.getNextEntry(); 
    } 

    zis.closeEntry(); 
    zis.close(); 
} 

} 
+0

selben Problem: Datei kann nicht gelöscht werden! –

+0

Können Sie bestätigen, dass dies nicht der Fall ist, weil die "Kopie" über dem Löschen noch läuft? – Chris

+0

@ Chris.how kann ich das überprüfen. Wenn ich kann dann kann ich Code löschen, sobald das Kopieren fertig ist. –

0

Ich denke, Ihr Problem mit OS-Dateipuffer, die manchmal nicht geleert werden, wenn Sie versuchen, Datei zu löschen. Haben Sie versucht, sourceFile.deleteOnExit() statt FileUtils.forceDeleteOnExit (sourceFile) zu verwenden? Sie können auch versuchen sourceFile.canWrite vor dem Löschen zu überprüfen (möglicherweise hilft es kann) Sie können auch versuchen, Fileinputstream() zu verwenden, vor dem Löschen:

FileInputStream fi = new FileInputStream(sourceFile); 
fi.getFD().sync(); 
+0

ich versuchte mit deleteOnExit() auch das gleiche Problem exit.i hat keine FileInputStream verwendet, weil ich dachte, es könnte der cuprit sein –

+0

SourFile.Canwrite liefert immer wahr !! –

Verwandte Themen