Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在内存中使用仅文件API_C++_Performance - Fatal编程技术网

C++ 在内存中使用仅文件API

C++ 在内存中使用仅文件API,c++,performance,C++,Performance,有些API只支持输出到文件。e、 g.将BMP转换为PNG的库,仅具有保存(文件)选项-无内存功能。不过,磁盘IO速度很慢,有时您只需要内存操作 这样的问题有没有通用的解决方案?可能是一个伪造的内存中文件,允许用户使用库,但不支付磁盘IO的性能惩罚?通常,“临时文件”的操作系统接口(例如tmpfile()/tmpnam())实际上会在磁盘缓存中创建存储,以便操作进入内存而不是磁盘这不是一个完美的解决方案,因为它依赖于操作系统,而不是在进程空间中显式地创建一个类似文件的缓冲区,但这可能是最简单的解

有些API只支持输出到文件。e、 g.将BMP转换为PNG的库,仅具有保存(文件)选项-无内存功能。不过,磁盘IO速度很慢,有时您只需要内存操作


这样的问题有没有通用的解决方案?可能是一个伪造的内存中文件,允许用户使用库,但不支付磁盘IO的性能惩罚?

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


tmpnam()是通用的C STDLIB接口,但是各种OSES可能有自己的方法来更精确地做你想要的。例如,Windows已经../P>< P>没有一般的答案,但是当你标记了问题C++时,你应该记住,在<代码> < /C>标准头中声明的内存中STRING SUSTER类提供了TH。这些库通常只接受文件名作为输入,而不是ostream。在这种情况下,虽然不是真正的编程解决方案,但您可以设置。

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

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

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


如果库需要查找对文件的访问权限,那么添加到“全部内存”解决方案将是微不足道的,但添加到缓冲解决方案则有点棘手。虽然这并非不可能,但仍然值得考虑内存开销是否是您的问题。

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

这里有一个,现在我确信有些地方有完整的实现可以为您实现,但我找不到。

使用

和(和)都存在类似的构造


但是我认为设置所有这些结构不值得。选择一个替代库,或者如果可能的话,直接写到磁盘。

我的通用解决方案是“找到另一个API”它并不总是有效的,但是对于很多任务来说,这是可能的。很有可能找到一个可以在内存中工作的PNG--BMP转换器。< / P>我不打算把它当作一个答案,因为我对C++几乎一无所知,但是可能会玩内存映射文件。内存映射文件在创建文件FRO时不起作用。m是您传入的文件名。这些库通常只接受一个文件名作为输入,而不是ostream…所以您是说临时文件和内存写入一样快?Assaf,这取决于您的操作系统、配置和RAM的大小。正确设置后,您可以完全避免物理磁盘。仍然会有一些文件系统开销。tmpnam()如果你需要一个文件名而不是一个文件句柄。我想他问的是API,它只需要一个文件名,然后自己打开文件。是的。但是我几乎不认为我可以在客户的机器上设置一个RAM磁盘,这样一些实用功能就不会写入磁盘了。我希望我可以。但是我一直在使用这个库,并写入磁盘太慢了。命名管道是否适用于任何使用stdio写入文件的库?是的,对于win32 fopen/fwrite/…而言,只要库接受\\.\pipe\nameOfPipe这样的路径,并且您甚至可以让多个客户端连接到同一命名管道。在*nix上,它与其他任何库一样是一个文件/节点,因此是的,open/write/…也可以工作。耶,+1绕道。在宣布软件“稳定”之前,您必须进行一些繁重的测试,但iirc它是为microsoft内部使用而构建的,用于向现有的较旧应用程序添加dcom功能(?)