在内存中使用仅文件API

时间:2009-06-28 08:34:13

标签: c++ performance

某些API仅支持输出到文件。例如一个将BMP转换为PNG并且只有一个Save(文件)选项的库 - 没有内存功能。但磁盘IO速度很慢,有时您只需要内存操作。

是否存在针对此类问题的通用解决方案?可能是一个假的内存文件,允许一个人使用该库,但不支付磁盘IO的性能损失?

7 个答案:

答案 0 :(得分:3)

使用named pipes

WindowsUnix(以及this)都存在类似的结构。

但我不相信设置所有这些结构的努力值得。如果可能,请选择替代库或只写入磁盘。

答案 1 :(得分:2)

您可以捕获文件I / O API(例如,使用detoursN-CodeHook),并将它们路由到您的实现(将使用内存)。

这是一个walk thought of someone who done something slimier,现在我确定哪些地方有完整的实施方案可以帮到你,但我找不到。

答案 2 :(得分:1)

通常,“临时文件”的OS界面(例如tmpfile() / tmpnam())实际上会在磁盘缓存中创建存储,以便操作进入内存而不是磁盘(达到一定限制) )。它不是一个完美的解决方案,因为它依赖于操作系统,而不是在进程空间内显式创建类似文件的缓冲区,但它可能是最简单的。

tmpnam()是通用的C stdlib接口,但各种操作系统可能有自己的方法来更精确地执行您想要的操作。例如,Windows有GetTempFileName()

答案 3 :(得分:1)

这些库通常只接受文件名作为输入,而不是ostream
在这种情况下,虽然不是真正的编程解决方案,但您可以设置a ram disk。< p>

答案 4 :(得分:0)

对此没有一般性的答案,但是当你标记你的问题C ++时,你应该记住在<sstream>标准头中声明的内存中的字符串流类提供与世界相同的接口。 fstreams,在阅读和写作方面。

答案 5 :(得分:0)

如果库允许你提供自己的文件访问函数实现(通过函数指针或接口类,很多,你只需要稍微搜索头文件)然后你应该能够提供内存解决方案,没有太多问题。根据我正在使用的系统的内存要求,我通常采用两种方法。

第一种是在Open()调用的实现中预先为文件分配所有内存。然后,您只需要将memcpy()放入缓冲区并更新您在Write()调用中通过缓冲区的距离。最后,在Close()的实现中,只需使用平台提供的任何IO功能将文件写入磁盘即可。这种方法的优点是它易于实现,但缺点是如果你不知道最终文件的大小,内存使用是不可预测的。你需要1kb缓冲区还是10mb缓冲区?你有足够的内存用于整个文件吗?

第二种方法可以避免上述实现的内存问题,但只有在系统尚未提供缓冲IO时才真正有用。这种方法是使用固定大小的单个缓冲区(例如32kb)并使用Write()实现像以前一样填充缓冲区。但是,每次达到32kb限制时,都会将缓冲区写入磁盘并清空,准备再次填充。您的Close()实现只需要编写任何剩余的数据磁盘。您需要的缓冲区大小取决于您使用的系统,因此您可能需要进行一些实验才能找到最佳尺寸。

如果库需要访问该文件,那么添加到“all in memory”解决方案将是微不足道的,但添加到缓冲解决方案有点棘手。虽然并非不可能,但仍然值得考虑是否存在内存开销问题。

答案 6 :(得分:0)

我的通用解决方案是“找到另一个API”。它不会始终工作,但对于很多任务,它是可能的。有可能找到一个PNG - &gt;可以在内存中工作的BMP转换器。