2013-06-07 28 views
5

Mam do czynienia z nietypowym problemem. Buduję narzędzie, które ma być uruchamiane co 5 minut. Przejmie pliki zip z określonego katalogu i wyodrębni pliki (w zależności od nazwy pliku) do miejsca docelowego. Używam zipentry, aby pobrać każdą nazwę pliku w pliku zip, a następnie wyodrębnić w razie potrzeby, a następnie zarchiwizuję je (pliki zip, gdy skończę wszystkie pliki w pliku ZIP) do określonego katalogu, a następnie usuniemy plik zip. Ale czasami (nie zawsze) pliki zip nie są usuwane. Ponieważ używam fileutils.forcedelete(). Otrzymuję wyjątek: nie można usunąć pliku. Więc zmieniłem kod na użycie fileutils.forcedeleteonexit(), ale niektóre pliki pozostają w źródle.Nie można usunąć pliku zip po rozpakowaniu?

Oto przykład z mojego kodu:

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); 

Brak strumienie używane, ale jestem coraz blokadę na plikach czasami (nie zawsze). Co wydaje się być tutaj błędem? Czy to ekstrakcja zip4j powoduje problem lub cokolwiek innego? Używam zip4j 1.3.1.

+3

Jaki OS? Windows ma notorycznie problemy z uchwytami plików i usuwanie ... – fge

+0

@fge: Windows.tried w moim lokalnym i na serwerze (Windows Server 2008 R2) –

+0

@fge Nie mogę powiedzieć, ile razy Windows powiedział mi "plik w użyj "podczas próby usunięcia archiwum po wyodrębnieniu jego danych, ale z pewnością było to więcej razy, niż mogę liczyć na obie ręce. Czy jest to wina programów, które nie zamykają poprawnie swoich uchwytów plików, czy też Windows utrzymuje pewne pliki otwarte nawet po zamknięciu programów? – JAB

Odpowiedz

0

Użyj apache-commons IO na FileDeleteStrategy. Coś jak:

FileDeleteStrategy.FORCE.delete(file); 

Aktualizacja:

Powinno być sposobem IO jest obsługiwane w aplikacji. Napisałem prosty kod, który kopiuje plik zip do tymczasowego suwaka, spuszcza tymczasowy suwak i po kilku sekundach go kasuje. Tutaj:

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

ten sam problem: nie można usunąć pliku! –

+0

Czy możesz potwierdzić, czy nie jest tak, ponieważ powyższe polecenie "copy" jest nadal w toku? – Chris

+0

@ Chris.how mogę to sprawdzić.if mogę wtedy mogę kod, aby usunąć po zakończeniu kopiowania. –

0

Myślę, że twój problem związany z buforami plików systemu operacyjnego, które czasami nie są przepłukiwane, gdy próbujesz usunąć plik. Czy próbowałeś użyć sourceFile.deleteOnExit() zamiast FileUtils.forceDeleteOnExit (sourceFile)? Ponadto można spróbować sprawdzić sourceFile.canWrite przed usunięciem (może być może to pomaga) Można również spróbować użyć FileInputStream() przed usunięciem:

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

próbowałem z deleteOnExit() również ten sam problem exit.i nie użyłem żadnego FileInputStream ponieważ myślałem, że to może być cuprit –

+0

sourFile.canwrite zawsze zwraca true !! –