小编典典

File.createNewFile()随机失败

java

我建立了一个简单的测试,它可以无限循环地创建和删除文件(名称不变)。该测试确实运行了几秒钟(有时超过77,000次迭代!),然后由于以下异常而失败:

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)

这是测试逻辑:

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

这怎么可能?删除呼叫不会失败。它会说明一切。因此删除总是成功但createNewFile失败。这就是MSDN关于Win32
API函数的说法DeleteFile

DeleteFile函数在关闭时将文件标记为要删除。因此,在关闭文件的最后一个句柄之前,不会发生文件删除。随后调用CreateFile打开文件失败,并显示ERROR_ACCESS_DENIED。

所以createNewFile不关闭文件?openjdk源告诉我们文件 关闭:

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

谁能解释这种行为?


阅读 493

收藏
2020-11-30

共1个答案

小编典典

我在写问题时找到了解释。我仍然发布问题,因为我想分享我学到的东西。

我的应用程序不是系统访问文件的唯一过程。例如,Windows搜索索引服务可能会打开此文件,因为它想将其添加到索引中。或Windows资源管理器(如果要更新视图)。

2020-11-30