FileNotFound(拒绝访问)java.io上的异常

时间:2011-11-10 07:16:42

标签: java file-io file-permissions

运行此程序时为什么会出现此错误?这发生在随机迭代之后。通常在第8000次迭代之后。

public static void main(String[] args)
{
    FileWriter writer = null;
    try
    {
        for(int i = 0; i < 10000; i++)
        {
            File file = new File("C:\\Users\\varun.achar\\Desktop\\TODO.txt");

            if(file.exists())
            {
                System.out.println("File exists");
            }
            writer = new FileWriter(file, true);
            writer.write(i);
            System.out.println(i);
            writer.close();
            if(!file.delete())
            {
                System.out.println("unable to delete");
            }

            //Thread.sleep(10);
            //writer = null;
            //System.gc();
        }
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
    finally
    {
        if(writer != null)
        {
            try
            {
                writer.close();
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}

发生异常后,该文件不存在。这意味着它正在删除,但FIleWriter尝试在此之前获取锁,即使它不是多线程程序。是因为Windows没有足够快地删除文件,因此FileWriter没有锁定?如果是这样,那么file.delete()方法在Windows实际删除它之前返回?

我如何解决它,因为我在负载测试我的应用程序时遇到了类似的问题。

编辑1:Stacktrace:

java.io.FileNotFoundException: C:\Users\varun.achar\Desktop\TODO.txt (Access is denied)     
at java.io.FileOutputStream.openAppend(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:192)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:116)
    at java.io.FileWriter.<init>(FileWriter.java:61)

编辑2 :在程序中添加了file.exists()和file.delete条件。和新的stacktrace:

7452
java.io.FileNotFoundException: C:\Users\varun.achar\Desktop\TODO.txt (Access is denied)
    at java.io.FileOutputStream.openAppend(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:192)
    at java.io.FileWriter.<init>(FileWriter.java:90)
    at com.TestClass.main(TestClass.java:25)

编辑3 线程转储

TestClass [Java Application]    
    com.TestClass at localhost:57843    
        Thread [main] (Suspended (exception FileNotFoundException)) 
            FileOutputStream.<init>(File, boolean) line: 192    
            FileWriter.<init>(File, boolean) line: 90   
            TestClass.main(String[]) line: 24   
    C:\Users\varun.achar\Documents\Softwares\Java JDK\JDK 6.26\jdk\jre\bin\javaw.exe (09-Nov-2011 11:57:34 PM)  

编辑4 :程序在具有相同操作系统的不同计算机上成功运行。现在,我如何确保应用程序在部署的计算机中成功运行?

9 个答案:

答案 0 :(得分:4)

在任何操作系统上,您一次只能拥有一定数量的打开文件/线程。您似乎达到了操作系统限制。尝试在循环内将文件设置为null。

答案 1 :(得分:2)

如果我正确理解了您的堆栈跟踪,则在尝试创建新的FileWriter时会出现异常。如果不进一步调查,就不可能知道原因。

  • 返回值可能会说明问题。特别是,请检查File.delete()返回的内容。
  • 在尝试创建新FileWriter之前,请检查File.exists()返回的内容。

如果之前的delete()返回true并且exists()之后还返回true,则在单线程程序中,那确实是奇怪的。

编辑:所以似乎删除成功,之后该文件不存在。当然,它应该如何工作,所以FileWriter抛出异常的原因很奇怪。还有一个想法,试试检查File.getParentFile().canWrite()。也就是说,写入目录的权限是否会以某种方式消失。

编辑2:

  

请勿在具有相同操作系统的其他计算机上获取错误。现在,我如何确保此错误不会出现在将要部署的应用程序中?

到目前为止,您的一台计算机工作不正常且一台正常运行。也许你可以在更多机器上试试。第一台机器可能会以某种方式损坏并导致错误。令人惊讶的是,数字计算机及其程序(我的意思是操作系统和Java,不一定是你的程序)经常可能只是“有点破碎”,因此它们几乎在所有时间都能完美地工作,但是随着一些特定的硬件随机失败&安培;用例 - 通常在负载很重的情况下 - 类似于多线程程序的错误行为。成为你的问题不一定是你的错: - )

坦率地说,让确定错误不会出现在机器X中的唯一方法是在机器X上运行该程序。不寻常的东西,如创建和删除相同的文件8000次快速继承容易出错,即使它“应该”有效。计算机,操作系统和API 完美。你做的越不寻常的东西越多,瑕疵就越容易实现,因为不正常的使用通常不如日常操作那么彻底。

答案 2 :(得分:2)

我遇到了同样的问题,一个java程序(单线程)打开,删除然后连续重新打开同一个文件。

在某些Windows系统上,我们遇到了与此处报告的相同的问题,在Linux,Solaris和其他各种Windows系统上,它可以正常工作。

使用SysInternals Process Monitor (now MS) 跟踪程序,清除删除操作首先在操作系统级别完成,并清除后续打开失败,并显示PENDING DELETE状态。

因此,在实际删除文件之前,OS / NTFS /磁盘级别似乎有一些轻微的延迟,这似乎是我们案例中随机失败的原因。

作为一种解决方法,我更改了.delete()调用,而只是在其顶部写入新的FileWriter(文件),这似乎正在起作用。

在所有系统上都没有出现这个问题,一个总是会失败的特定型号,都是在没有固定数量的循环之后,是带有WD Smartdrive的Windows 7 / Dell Lattitude E6420,而我的Windows 7 /戴尔精密M4600 (使用固态硬盘)或使用Linux的T3400我从未遇到过这个问题。

干杯 - 马克

答案 3 :(得分:1)

你能有条件地尝试写入文件吗?

使用file.exists然后写入它,这样您就可以避免任何其他问题。很难说这个例外。

http://download.oracle.com/javase/6/docs/api/java/io/File.html#exists()

你能否在那时发布一个线程转储,只是为了进一步调试它。

请在再次写作之前冲洗作者。

答案 4 :(得分:1)

这可能是一个很长的镜头,但是,您是否可以尝试使用不直接放在桌面上的文件。而不是:

"C:\\Users\\varun.achar\\Desktop\\TODO.txt"

尝试:

"C:\\Users\\varun.achar\\SomeOtherDirectory\\TODO.txt"

操作系统可能在这里用所有桌面挂钩杀死你......

根据评论编辑:

  • “坏”机器上是否有预定的作业?
  • 您是否有系统管理员来代替调试环境?
  • 这是否适用于 clean Windows安装? [95%的可能性]
  • 由于根本原因似乎是环境,而不是解决Windows配置问题,您是否能够继续执行其他任务,并将其留给那些保留系统之间差异列表的人?

答案 5 :(得分:0)

这些是您在删除文件http://www.java2s.com/Code/Java/File-Input-Output/DeletefileusingJavaIOAPI.htm

之前应该处理的方案

至少检查程序中的返回值。

答案 6 :(得分:0)

感谢大家的帮助,但最终解决了这个问题。

public static void main(String[] args)
    {
        FileWriter writer = null;
        try
        {
            for(int i = 0; i < 10000; i++)
            {
                File file = new File("C:\\tenant-system-data\\abc.txt");
                if(!file.getParentFile().canWrite())
                {
                    System.out.println("parent file error");
                }
                if(file.exists())
                {
                    System.out.println("File exists");
                }
                int count = 0;
                while(count++ < 5)
                {
                    try
                    {
                        file.createNewFile();
                        break;
                    }
                    catch(IOException e)
                    {
                        try
                        {
                            Thread.sleep(100);
                        }
                        catch(InterruptedException e1)
                        {
                            e1.printStackTrace();
                        }

                    }
                }
                writer = new FileWriter(file, true);
                writer.write(i);
                System.out.println(i);
                writer.close();
                if(!file.delete())
                {
                    System.out.println("unable to delete");
                }

                //Thread.sleep(10);
                //writer = null;
                //System.gc();
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(writer != null)
            {
                try
                {
                    writer.close();
                }
                catch(IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

答案 7 :(得分:0)

我遇到了同样的问题(FileWriter&amp; Access Denied)。

我的猜测原因是:Windows 7锁定了文件,因为在资源管理器窗口中显示了文件内容的预览(在窗口中选择了该文件)。

解决方案:我在资源管理器窗口中取消选择了该文件。并且IOException消失了。

答案 8 :(得分:-2)

您在目录中拥有删除权限,但没有创建权限。