【问题标题】:Can I get a FILE* backed by data already in memory?我可以获得由内存中已有数据支持的 FILE* 吗?
【发布时间】:2014-04-28 05:04:27
【问题描述】:

我的代码目前使用一个库,我将 FILE* 传递给它,它使用 fread() CRT API 读取一堆复杂的配置数据。我想移动文件以成为文件中的嵌入式资源(Windows DLL)。不幸的是,读取 Windows 资源会直接将数据作为 void*.... 传递给库。

我想要的是能够获得由内存缓冲区而不是磁盘上的文件支持的 FILE*。 Windows 有 CreateStreamOnHGlobal(),但它使用 IStream*,我需要一个 FILE*。不幸的是,我找不到任何适用于 Windows 的解决方案。 这可能吗?

我可以使用的解决方案是将资源数据写入临时文件,将临时文件传递给配置解析器,然后删除该文件....但效率极低,我处理大量数据。

【问题讨论】:

  • 我认为内存映射文件可能会给你你正在寻找的东西。在 Wikipedia 上查看 Memory-mapped file 或在 MSDN 上查看 Memory-Mapped Files
  • 我需要相反的内存映射文件。 MMF 让您将文件视为内存;我需要做的是将内存视为文件。不过感谢您的建议。
  • 感谢您的澄清。我希望你能找到改变你的库以使用更合适的抽象来利用内存中的数据的动机。

标签: c windows file io fread


【解决方案1】:

您真正想要的是相当于 Windows 上的fmemopen()。不存在这样的等价物。

您可以使用命名管道作为解决方法。您应该能够使用fopen() 打开命名管道的读取端。然后资源提供者将FILE * 传递给配置解析器,而其他一些线程将资源数据写入命名管道的写入端。这应该没问题,只要解析器只想对文件进行顺序读取(而不是查找,这在管道上不起作用)。

如果你愿意使用Cygwin,它提供fmemopen()

【讨论】:

  • 谢谢。这是个好建议。痛苦……但一个好主意。 :-)
  • 我只是想出了一个更严重的黑客攻击。将数据附加到 DLL 本身的末尾。使用fopen() 将 DLL 作为常规文件打开,然后寻找数据的开头,并将其传递给您的库。
【解决方案2】:

https://github.com/tamatebako/fmem 是内存文件的不同平台/版本特定实现的包装器

它依次尝试以下实现:

  • open_memstream。

  • fopencookie,具有不断增长的动态缓冲区。

  • funopen,具有不断增长的动态缓冲区。

  • WinAPI 临时内存支持文件。

    当没有其他方法可用时,fmem 回退到 tmpfile()

【讨论】:

    猜你喜欢
    • 2021-04-28
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 2014-12-01
    • 2013-09-15
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多