运行此程序时为什么会出现此错误?这发生在随机迭代之后。通常在第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 :程序在具有相同操作系统的不同计算机上成功运行。现在,我如何确保应用程序在部署的计算机中成功运行?
答案 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"
操作系统可能在这里用所有桌面挂钩杀死你......
答案 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)
您在目录中拥有删除权限,但没有创建权限。