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

我可以在Windows中创建一个只存在于内存中的文件吗?如果可以,如何创建?,windows,winapi,temporary-files,memory-mapped-files,Windows,Winapi,Temporary Files,Memory Mapped Files,本问题并非与任何现有问题的重复: -这个问题与Java的文件API无关 -这与我的要求很接近,只是OP没有要求如何从内存创建文件,以便共享文件并将其传递给子进程 我也不是在问Win32的内存映射文件,因为它们本质上与我所追求的相反:内存映射文件是磁盘上映射到进程虚拟内存空间的文件,而我想要的是存在于操作系统文件系统(而不是磁盘的物理文件系统)中的文件与装载点类似,该文件的数据映射到内存中的现有缓冲区。 也就是说,对于内存映射文件,写入/写入特定缓冲区地址和内存中偏移量处的字节将导致修改与文件

本问题并非与任何现有问题的重复:

  • -这个问题与Java的
    文件
    API无关
  • -这与我的要求很接近,只是OP没有要求如何从内存创建文件,以便共享文件并将其传递给子进程
  • 我也不是在问Win32的内存映射文件,因为它们本质上与我所追求的相反:内存映射文件是磁盘上映射到进程虚拟内存空间的文件,而我想要的是存在于操作系统文件系统(而不是磁盘的物理文件系统)中的文件与装载点类似,该文件的数据映射到内存中的现有缓冲区。
    • 也就是说,对于内存映射文件,写入/写入特定缓冲区地址和内存中偏移量处的字节将导致修改与文件开头相同偏移量处的字节-但文件实际存在于磁盘上,这不是我想要的
详细说明并提供上下文:

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

    • 它通过将流保存到磁盘上的临时文件并传递该流的文件名,将数据传递给这些单独的应用程序
    • 不幸的是,它无法将内容写入子进程的
      stdin
      ,因为其中一些程序希望磁盘上有一个文件,而不是从
      stdin
      读取
  • 此外,虽然它运行的机器有很多RAM(因此在内存中保留缓冲流是很好的),但它的硬盘速度较慢,这也是避免在磁盘上存储临时文件的另一个原因

  • 我希望避免不必要的缓冲和复制—理想情况下,我希望将整个1-10MB请求流式传输到单个内存缓冲区中,然后将该缓冲区暴露给其他进程,并将该缓冲区用作临时文件的备份

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

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

    • 是使用Microsoft的RAM磁盘驱动程序平台实现的RAM磁盘,但据我所知,虽然它更像
      tmpfs
      ,因为它可以创建仅存在于内存中的文件,但它不允许文件的数据由运行进程直接访问的缓冲区(或共享内存缓冲区)备份
with
hFile=INVALID\u HANDLE\u VALUE
“创建指定大小的文件映射对象,该对象由系统分页文件而不是文件系统中的文件支持”

来自雷蒙德·陈的:

换句话说,“由系统分页文件支持”只是指“像常规虚拟内存一样处理”

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


啊,我不知道你可以创建一个页面文件支持的内存映射文件-但是我如何才能将该文件映射到现有的共享内存缓冲区?我知道我可以使用
MapViewOffilex
将内存映射文件(包括页面文件备份的映射文件)映射到进程的内存空间,但我想我必须先使用
MapViewOffilex
并将缓冲区存储在那里,但我想知道如果我传入一个指向已分配缓冲区的指针,会发生什么情况。更新:事实证明你不能。
MapViewOffilex
的文档说明:“如果指定的内存区域尚未被调用进程使用,则函数将成功”。Bummer.@Dai根据使用情况,您可以使用其他方法,并使用映射与和共享。分页文件支持的映射不是程序可以打开的常规文件,因此它不满足要求。程序可以使用该属性创建一个常规文件,以尽可能避免写入磁盘。@ErykSun
当然不是一个常规文件。另一方面,“只存在于内存中”的文件(如标题所示)不能是“常规”文件。但是,即使不使用
CreateFile
,也可以打开命名映射。etc的可能副本似乎没有用于此目的的用户应用程序级API。这可以通过实现一个驱动程序来实现。你介意分享一下使用RAM的原因吗?为了提高读/写速度?@RitaHan MSFT我想将1GB的数据从一个进程传递到一个新的子进程:但该进程只能接受一个文件名,而不能通过stdin
——我希望避免在内存中复制1GB的数据。