Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 内存映射Windows中具有共享属性的文件(因此文件不会被锁定以防止删除)_Java_Windows_Mmap_Bytebuffer_Memory Mapped Files - Fatal编程技术网

Java 内存映射Windows中具有共享属性的文件(因此文件不会被锁定以防止删除)

Java 内存映射Windows中具有共享属性的文件(因此文件不会被锁定以防止删除),java,windows,mmap,bytebuffer,memory-mapped-files,Java,Windows,Mmap,Bytebuffer,Memory Mapped Files,是否有任何方法可以将文件内容映射到Windows中的内存中,而该内存中没有对文件的锁定(特别是,在仍处于mmap状态时可以删除该文件) Java NIO在Windows中库mmap文件的方式是,当堆中还有任何未垃圾收集的MappedByteBuffer引用时,无法删除映射文件。JDK团队声称这是Windows的一个限制,但仅当文件是mmap时,而不是当它们作为常规文件打开时: (显然,如果文件在mmap'd时被删除,那么mmap'd区域到底会发生什么情况在Windows文件语义中是有争议的,尽

是否有任何方法可以将文件内容映射到Windows中的内存中,而该内存中没有对文件的锁定(特别是,在仍处于mmap状态时可以删除该文件)

Java NIO在Windows中库mmap文件的方式是,当堆中还有任何未垃圾收集的MappedByteBuffer引用时,无法删除映射文件。JDK团队声称这是Windows的一个限制,但仅当文件是mmap时,而不是当它们作为常规文件打开时:

(显然,如果文件在mmap'd时被删除,那么mmap'd区域到底会发生什么情况在Windows文件语义中是有争议的,尽管它在Linux中定义得很好。)

作为参考,无法在内存映射(或尚未垃圾收集)时删除文件在Java中造成了许多问题:

取消映射操作不受支持还有一些安全原因:

更新:另请参见:

如前所述,如果节(文件映射)是在没有属性的情况下以两种方式创建的,则我们可以删除映射文件:

  • 打开带有标志的文件-该文件为 在其所有句柄关闭后立即删除,其中 包括指定的句柄和任何其他打开或复制的句柄 把手。或者我们可以使用或 用旗子打电话
  • 通过电话。确实
    NtDeleteFile
    open 带有
    file\u DELETE\u ON\u CLOSE
    标志和特殊内部标记的文件 性情这是打电话更多 高效比较正常打开的文件,然后关闭该文件句柄
在代码中,这看起来像

#ifndef FILE_SHARE_VALID_FLAGS
#define FILE_SHARE_VALID_FLAGS 0x00000007
#endif

NTSTATUS Delete1(PCWSTR FileName)
{
    HANDLE hFile = CreateFile(FileName, DELETE, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        return RtlGetLastNtStatus();
    }
    CloseHandle(hFile);
    return 0;
}

NTSTATUS Delete2(PCWSTR FileName)
{
    UNICODE_STRING ObjectName;

    if (RtlDosPathNameToNtPathName_U(FileName, &ObjectName, 0, 0))
    {
        OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };

        NTSTATUS status = ZwDeleteFile(&oa);

        RtlFreeUnicodeString(&ObjectName);

        return status;
    }

    return STATUS_UNSUCCESSFUL;
}
请注意,此处的调用失败,状态为-
status\u无法删除
。我建议在这里调用
RtlGetLastNtStatus()
,因为win32到错误代码的映射
NTSTATUS
不是内射的,并且经常丢失有价值的信息。说
STATUS\u CANNOT\u DELETE
映射到
ERROR\u ACCESS\u DENIED
。但存在另一个巨大的
NTSATUS
代码,该代码也映射到
错误\u访问\u拒绝
错误访问被拒绝
不仅
状态访问被拒绝
(实际访问被拒绝)。获取
状态\u无法\u删除
此处的信息更多比较
错误\u访问被拒绝
RtlGetLastNtStatus
与从ntdll.dll导出的
GetLastError
具有完全相同的签名(因此包括ntdll.lib或ntdllp.lib)


@RbMm,我们可以在关闭打开时删除映射文件(通过
CreateFile
/
CloseHandle
NtDeleteFile
)。在这种情况下,文件系统只检查而不是
MmFlushForDelete
。起初这可能是个错误,但现在它已经是标准的了。@eryksun-是的,你纠正了。我们可以通过这种方式删除文件,如果节创建时没有
SEC\u IMAGE
attribute@eryksun,是的,如果文件句柄仍未关闭,则从
CreateFile
调用中盲目返回
RtlGetLastNtStatus()
是可疑的<代码>创建文件可能会在未设置最后一个NT状态值的情况下失败。例如,如果路径太长,翻译将失败,出现
状态\u NAME\u too\u long
,在这种情况下,
创建文件
只需调用
RtlSetLastWin32Error(未找到错误路径)
。状态值未保存在TEB
LastStatusValue
中。在第二种情况下,我建议使用
rtldospathname tontpathname\U\U with status
,以便我们可能知道调用失败的原因。此函数在NT 5.2+(Server 2003 SP1及更高版本)中可用,因此除非您必须支持旧版本,否则它不是问题。是的,当来自WinAPI时,我们可能需要这两个版本,但我们必须小心,并将其留给调用方。我们可以捕获
CreateFile
last status值作为out参数,并返回Windows错误代码。来电者可以决定是否相关。例如,调用方可以忽略
ERROR\u PATH\u NOT\u FOUND
的状态。澄清获取
错误访问被拒绝的原因非常有用(一个常见且恼人的例子是
状态文件\u是\u目录
)。@LukeHutchison-当您可以删除文件时,即使文件正在使用(映射)。文件改为完全删除-从目录中取消映射,不再可见。我们可以说用这样的名称创建新文件。但文件数据最终将被删除后,所有使用它结束。-但这需要win10的最新版本
extern "C" NTSYSCALLAPI NTSTATUS NTAPI RtlGetLastNtStatus();