File.createNewFile () randomly not working

I created a simple test that creates and deletes a file (the name does not change) in an infinite loop. The test runs for several seconds (sometimes more than 77,000 iterations!), And then with this exception:

Exception in thread "main" java.io.IOException: Access is denied at java.io.WinNTFileSystem.createFileExclusively(Native Method) at java.io.File.createNewFile(Unknown Source) at DeleteTest.main(DeleteTest.java:11) 

Here's the test logic:

 final File f = new File(pathname); while (true) { final boolean create = f.createNewFile(); if (!create) { System.out.println("crate failed"); } else { final boolean delete = f.delete(); if (!delete) { System.out.println("delete failed"); } } } 

How is this possible? The call is not interrupted. That will say. Therefore, deletion always succeeds, but createNewFile fails. This is what MSDN says about the win32 api DeleteFile :

The DeleteFile function marks a file for deletion when closing. Therefore, file deletion does not occur until the last file descriptor is closed. Subsequent calls to CreateFile to open the file fail ERROR_ACCESS_DENIED.

So, createNewFile does not close the file? The openjdk source tells us that the file is closed:

 JNIEXPORT jboolean JNICALL Java_java_io_Win32FileSystem_createFileExclusively(JNIEnv *env, jclass cls, jstring pathname) { jboolean rv = JNI_FALSE; DWORD a; WITH_PLATFORM_STRING(env, pathname, path) { int orv; int error; JVM_NativePath((char *)path); orv = JVM_Open(path, JVM_O_RDWR | JVM_O_CREAT | JVM_O_EXCL, 0666); if (orv < 0) { if (orv != JVM_EEXIST) { error = GetLastError(); // If a directory by the named path already exists, // return false (behavior of solaris and linux) instead of // throwing an exception a = GetFileAttributes(path); if ((a == INVALID_FILE_ATTRIBUTES) || !(a & FILE_ATTRIBUTE_DIRECTORY)) { SetLastError(error); JNU_ThrowIOExceptionWithLastError(env, path); } } } else { JVM_Close(orv); rv = JNI_TRUE; } } END_PLATFORM_STRING(env, path); return rv; } 

Can anyone explain this behavior?

+1
source share
3 answers

I found an explanation when writing the question. I still asked a question because I wanted to share what I learned.

My application is not the only process in the system that accesses files. For example, the Windows Search Index service might open this file because it wants to add it to the index. Or Windows Explorer if it updates the view.

+2
source

Try the following:

 final File f = new File("file"); while (true) { final boolean create = f.createNewFile(); if (!create) { System.out.println("crate failed"); } else { final boolean delete = f.delete(); try { Thread.sleep(10); } catch (InterruptedException e) { System.out.println("..."); } if (!delete) { System.out.println("delete failed"); } } } 

Thus, we guarantee that the file will be deleted by deletion before calling createNewFile.

0
source

This issue reminds me of a problem I recently encountered with the File.renameTo () method. This (was it?) Due to this error in jvm:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213298

A strange workaround is to call System.gc () and re-rename the file again (and it works ...).

Not sure if you have a link to your problem, but maybe worth exploring ...

0
source

All Articles