【问题标题】:Delay when deleting directory recursively递归删除目录时的延迟
【发布时间】:2013-01-17 08:08:35
【问题描述】:

我有以下 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();
        }
    }

}

【问题讨论】:

  • Windows 阻止正在使用的文件。虽然不是 Groovy 专家,但我会指出 file &lt;&lt; Arrays.fill(new char[100], (char)'a')。那将需要打开一个句柄。在 java 中,我会说正在创建许多 FileOutputStream 对象,但它们都没有关闭。延迟允许 GC 释放对象,然后解锁文件。 Groovy 中有什么方法可以显式关闭文件吗?
  • 将其更改为使用withOutputStream,我知道它确实可以处理打开和关闭适当的资源,但它仍然失败。我不认为它是开放的胭脂流。
  • 我还应该注意,我用空文件尝试过这个并且没有错误。目录中的文件需要包含延迟发生的信息。
  • 对不起,我确实看错了你的帖子。我在删除文件时寻找错误,而不是在重新创建文件时。我也一直在谷歌搜索,发现&lt;&lt; 也应该关闭流。我的错。

标签: java windows groovy directory


【解决方案1】:

这似乎成功了:

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

}

仍然不确定删除文件夹时的延迟究竟来自何处,但我假设这只是文件系统的一个怪癖。

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 2018-10-15
    • 2016-04-18
    • 1970-01-01
    • 2010-10-21
    相关资源
    最近更新 更多