我可以在 Windows 中创建一个仅存在于内存中的文件吗?如果可以,如何创建?

Dai*_*Dai 6 windows winapi temporary-files memory-mapped-files

此问题与以下任何现有问题均不重复:

  • 如何将仅存在于内存中的对象文件作为文件存储在存储系统中?- 这个问题与Java的API无关File
  • 临时文件只存在于RAM中?- 这与我要问的很接近,除了OP没有询问如何从内存创建文件以共享将它们传递给子进程
  • 我也不是在问 Win32 的内存映射文件 - 因为它们本质上与我所追求的相反:内存映射文件是映射到进程虚拟内存空间的磁盘上的文件 - 而什么我想要的是一个存在于操作系统文件系统(而不是磁盘的物理文件系统)中的文件,就像安装点一样,并且该文件的数据映射到内存中的现有缓冲区。
    • 即,使用内存映射文件,在内存中的特定缓冲区地址和偏移量处写入/写入字节将导致距文件开头相同偏移量处的字节被修改 - 但该文件实际上存在于磁盘上,这这不是我想要的。

详细说明并提供背景:

  • 我有一个 ASP.NET Core 服务器端应用程序,它定期接收大小在 1 到 10MB 之间的请求流。该程序只能在 Windows / Windows Server 上运行,因此使用 Windows 特定的功能就可以了。
  • 75% 的时间我的应用程序只是自行读取这些流,仅此而已。
  • 但少数情况下,它需要有一个单独的应用程序读取它开始使用的数据,Process.Start并将文件名作为命令行参数传递。

    • 它通过将流保存到磁盘上的临时文件并传递该流的文件名,将数据传递到这些单独的应用程序。
    • 不幸的是,它无法将内容写入子进程stdin,因为其中一些程序需要磁盘上的文件而不是从stdin.
  • 此外,虽然它运行的机器有大量 RAM(因此将流缓冲在内存中很好),但它的HDD旋转速度很慢,生锈,这也是避免在磁盘上保存临时文件的进一步原因。

  • 我想避免不必要的缓冲和复制 - 理想情况下,我想将整个 1-10MB 请求流式传输到单个内存缓冲区中,然后将相同的缓冲区暴露给其他进程,使用相同的缓冲区作为支持一个临时文件。

  • 如果我在 Linux 上,我可以使用tmpfs- 它并不完美:

    • 据我所知,现有进程无法指示操作系统获取其虚拟内存的现有区域并将文件映射到tmpfs该内存区域,而是tmpfs仍然需要通过写入(即复制)所有内存来填充该文件。数据到其文件描述符 - 这与零拷贝系统的目标背道而驰。
  • Windows 的内置 RAM 磁盘功能仅限于通过第三方设备驱动程序为 RAM 磁盘实现提供基础 - 令我惊讶的是 Microsoft 从未向 Windows 提供内置 RAM 磁盘 GUI 或 API ,特别是考虑到它们相对简单。

    • ImDisk程序是使用 Microsoft 的 RAM 磁盘驱动程序平台的 RAM 磁盘的实现,但据我所知,虽然它更像是tmpfs可以创建仅存在于内存中的文件,但它不允许该文件的由正在运行的进程可直接访问的缓冲区(或共享内存缓冲区)支持的数据。

dxi*_*xiv 4

CreateFileMappingwith hFile = INVALID_HANDLE_VALUE创建指定大小的文件映射对象,该对象由系统分页文件而不是文件系统中的文件支持”。

\n

来自 Raymond Chen 的混乱的根源: \xe2\x80\x9c 由系统分页文件 \xe2\x80\x9d 支持

\n
\n

换句话说,由系统分页文件支持的\xe2\x80\x9c只是意味着\xe2\x80\x9像常规虚拟内存一样处理。\xe2\x80\x9d

\n

如果内存在调出之前被释放,那么它将永远不会被写入系统分页文件。

\n
\n

  • 分页文件支持的映射不是程序可以打开的常规文件,因此它不满足要求。该程序可以创建一个具有属性 [`FILE_ATTRIBUTE_TEMPORARY`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea?redirectedfrom=MSDN#caching-行为)以尽可能避免写入磁盘。 (3认同)