【问题标题】:in-memory FILE* (without disk access)内存中 FILE*(无磁盘访问)
【发布时间】:2017-04-13 23:42:05
【问题描述】:

我们有接受 FILE* (CImg) 的库。出于性能原因,我们希望在不访问磁盘的情况下处理已经在内存中的数据。目标平台是windows,不幸的是不支持fmemopen(和funopen)

char* buf = new char[sz];

FILE *fp = fopen("C:\\test.dat", "wb");
int r = setvbuf(fp, buf, _IOFBF, sz);

r = fwrite(src_buf, 1, sz, fp);     // Here r contains right size


fseek(fp, 0, SEEK_END);
size_t sz2 = ftell(fp);             // sz2 contains right size as well
rewind(fp);

// Test (something like this actually is somewhere deep inside library)
char* read_buf = new char[sz];
r = fread(read_buf, 1, sz, fp);     // Zero!

最终 fread() 无法读取任何内容...有什么建议吗?

【问题讨论】:

  • 为什么用 C++ 标记?这看起来像 C。
  • 有没有可能使用内存映射文件?
  • fp 以只写方式打开。
  • 你是如何将数据放到内存中的?在不知道这一点的情况下,没有人可以就如何从内存中读取它提供建议(无论是使用FILE * 还是任何其他方式)。
  • 您打开 fp 为“wb”,然后尝试从中读取?

标签: c fread stdio


【解决方案1】:

可能是因为您使用“wb”(只写)而不是“wb+”(读+写)打开

fopen() function

为了进一步帮助,您可以#include errno.h 并打印出错误代码和字符串。

printf( "errno: %d, error:'%s'\n", errno, strerror( errno ) );

【讨论】:

  • 谢谢!这有助于我们进行读取,但仍会导致将数据刷新到磁盘。在我们的案例中,RAM 驱动器可能是解决方案
  • @Victor 查看 snprintf 的 C 运行时源代码。 IIRC,它在内存缓冲区上做了一个假文件。不再有 windows 框,我会找到更好的参考。
【解决方案2】:

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

它依次尝试以下实现:

  • open_memstream。
  • fopencookie,具有不断增长的动态缓冲区。
  • funopen,具有不断增长的动态缓冲区。
  • WinAPI 临时内存支持文件。

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

【讨论】:

    【解决方案3】:

    对于我们的具体案例,我们发现 CImg 插件可以做到这一点。

    作为原始问题中的示例 - 至少 MSVC 运行时会将写入的内容刷新到磁盘本身。所以它不是 fmemopen() 的有效替换

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 2011-05-23
      • 2021-01-18
      • 2021-08-09
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多