2013-02-01 119 views
1

我有以下的Groovy測試腳本:延遲時刪除目錄遞歸

def dir = new File("test") 
dir.mkdirs() 

char[] data = new char[100] 
Arrays.fill(data, (char)'q') 

for(i in 0..1760){ 
    def file = new File(dir, "file$i") 
    file.createNewFile() 

    file.withOutputStream { os -> 
     os << data 
    } 
} 

def delete (File f){ 
    if(f.isDirectory()){ 
     for(File afile : f.listFiles()){ 
      delete(afile); 
     } 
     f.delete(); 
    }else{ 
     f.delete(); 
    } 
} 

delete(dir) 

dir.mkdirs() 

new File(dir, "file").createNewFile() //<-- java.io.IOException: Access is denied 

與失敗:

Caught: java.io.IOException: Access is denied 
java.io.IOException: Access is denied 
    at java_io_File$createNewFile.call(Unknown Source) 
    at test.run(test.groovy:29) 

但是,如果我修改測試腳本,看起來像這樣:

def dir = new File("test") 
dir.mkdirs() 

char[] data = new char[100] 
Arrays.fill(data, (char)'q') 

for(i in 0..1760){ 
    def file = new File(dir, "file$i") 
    file.createNewFile() 

    file.withOutputStream { os -> 
     os << data 
    } 
} 

def delete (File f){ 
    if(f.isDirectory()){ 
     for(File afile : f.listFiles()){ 
      delete(afile); 
     } 
     f.delete(); 
    }else{ 
     f.delete(); 
    } 
} 

delete(dir) 

Thread.sleep(1000) // <---- added a 1 second pause after deleting 

dir.mkdirs() 

new File(dir, "file").createNewFile() // <-- No Exception 

它不會再失敗。我在Windows 7 64位上運行Java 6。任何人都知道延遲來自何處或如何解釋它?

編輯:Java 6中發生

同樣的錯誤這就是爲什麼我標記它的Java(Groovy是隻是更容易編寫的例子)。下面是對應的測試,也沒有在Java中:

import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.Arrays; 


public class Test { 

    /** 
    * @param args 
    * @throws IOException 
    */ 
    public static void main(String[] args) throws IOException { 
     new Test().execute(); 
    } 

    public void execute() throws IOException{ 
     File dir = new File("test"); 
     dir.mkdirs(); 

     char[] data = new char[100]; 
     Arrays.fill(data, (char)'q'); 

     for(int x = 0; x < 1760; x++){ 
      File file = new File(dir, "file" + x); 
      file.createNewFile(); 

      FileWriter fw = null; 
      try{ 
       fw = new FileWriter(file); 
       fw.write(data); 
      }finally{ 
       if(fw != null){ 
        fw.close(); 
       } 
      } 
     } 

     delete(dir); 

     dir.mkdirs(); 

     new File(dir, "file").createNewFile(); //<-- java.io.IOException: Access is denied 
    } 

    private void delete (File f){ 
     if(f.isDirectory()){ 
      for(File afile : f.listFiles()){ 
       delete(afile); 
      } 
      f.delete(); 
     }else{ 
      f.delete(); 
     } 
    } 

} 
+0

正在使用Windows塊文件。雖然不是Groovy的專家,但我會指向'file << Arrays.fill(new char [100],(char)'a')'。這將需要打開一個句柄。在java中,我會說大量的FileOutputStream對象正在創建,但沒有關閉。延遲允許GC處置對象,然後解鎖文件。 Groovy有什麼方法可以顯式關閉文件? – SJuan76

+0

改成了使用'withOutputStream',我知道肯定手柄打開和關閉相應的資源,它仍然失敗。我不認爲這是一個喋喋不休的流程。 – FGreg

+0

我也應該注意到,我用空文件試過,並且沒有錯誤。目錄中的文件需要包含延遲發生的信息。 – FGreg

回答

0

這似乎做的伎倆:

import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.Arrays; 


public class Test { 

    /** 
    * @param args 
    * @throws IOException 
    */ 
    public static void main(String[] args) throws IOException { 
     new Test().execute(); 
    } 

    public void execute() throws IOException{ 
     File dir = new File("test"); 
     dir.mkdirs(); 

     char[] data = new char[100]; 
     Arrays.fill(data, (char)'q'); 

     for(int x = 0; x < 1760; x++){ 
      File file = new File(dir, "file" + x); 
      file.createNewFile(); 

      FileWriter fw = null; 
      try{ 
       fw = new FileWriter(file); 
       fw.write(data); 
      }finally{ 
       if(fw != null){ 
        fw.close(); 
       } 
      } 
     } 

     delete(dir); 

     //dir.mkdirs(); <-- commented out 
     while(!dir.mkdirs()); //<-- dir.mkdirs() will return false until the directory has been successfully re-created 

     new File(dir, "file").createNewFile(); 
    } 

    private void delete (File f){ 
     if(f.isDirectory()){ 
      for(File afile : f.listFiles()){ 
       delete(afile); 
      } 
      f.delete(); 
     }else{ 
      f.delete(); 
     } 
    } 

} 

仍不能確定在延遲刪除文件夾來的時候正好從,但我假設它只是文件系統的一個怪癖。