3

我正在 Linux 上编写一个简单的 C 程序,并希望使用现有库的 API,该 API 需要来自文件的数据。我必须将文件名作为 const char* 提供给它。但是我有数据,就像文件的内容一样,已经位于堆上分配的缓冲区中。有大量的 RAM,我们想要高性能。想要避免将临时文件写入磁盘,以看起来像文件的方式将数据提供给此 API 的好方法是什么?

这是我的代码的廉价假装版本:

奇妙图书馆.h:

int marvelousfunction(const char *filename);

normal-persons-usage.cpp,最初为其设计的库:

#include "marvelouslibrary.h"
int somefunction(char *somefilename)
{
    return marvelousfunction(somefilename);
}

我的程序.cpp:

#include "marvelouslibrary.h"
int one_of_my_routines() 
{
    byte* stuff = new byte[1000000];
    // fill stuff[] with...stuff!
    // stuff[] holds same bytes as might be found in a file

    /* magic goes here: make filename referring to stuff[] */

   return marvelousfunction( ??? );
}

需要明确的是,marvelouslibrary 不提供任何通过指针接受数据的 API 函数。它只能读取一个文件。

我想到了管道和 mkfifo(),但似乎是为了在进程之间进行通信。我不是这些事情的专家。命名管道是否可以在同一进程中读取和写入?这是明智的做法吗?

或者跳过聪明,使用计划“B”,即shddup并只写一个临时文件。但是,除了获得高性能之外,我想学习一些新东西并找出在这种情况下可能发生的事情。

4

5 回答 5

3

鉴于您可能具有以下功能:

char *read_data(const char *fileName)

我认为您将需要“跳过聪明,采用计划“B”,即关闭并编写一个临时文件。”

如果您可以挖掘并找出您正在进行的调用是否正在调用另一个函数,该函数采用 File * 或 int 作为文件描述符,那么您可以做得更好。

一个想法确实浮现在脑海中,您可以将代码写入内存映射文件而不是堆吗?这样你就可以在磁盘上已经有一个文件了,你可以避免复制(尽管它仍然在磁盘上),你仍然可以给函数调用文件名。

于 2009-03-01T18:46:12.333 回答
2

我不确定库函数想要什么样的输入……它需要路径/文件名,还是打开文件指针,还是打开文件描述符?

如果您不想破解库并且函数需要字符串(文件路径),请尝试在 /dev/shm 中创建临时文件。

否则,mmap 可能是最好的选择,请务必在使用 mmap() 时研究 posix_madvise() (或者如果使用临时文件,则研究其对应的 posix_fadvise() )。

看起来您一开始就在谈论很少的数据,所以我认为无论您采取什么方式,您都不会看到性能影响。

编辑

抱歉,我刚刚重新阅读了您的问题..也许我读得太快了。您无法提供以下功能:

char * foo(const char *filepath)

... 使用 mmap()。

如果您不能修改库以接受文件描述符(或作为路径的替代).. 只需使用 /dev/shm 和临时文件,它会非常便宜。

于 2009-03-01T06:41:28.160 回答
0

编辑:对不起。只需阅读问题。根据我在下面的建议,您分叉了一个备用进程,并且“不会出现在单个进程中工作”的问题。我也看不出你没有理由不能产生一个单独的线程来进行推送......


一点也不优雅,但你可以:

  1. 打开命名管道。
  2. 分叉一个除了尝试写入管道之外什么都不做的流媒体
  3. 传递管道的名称

这应该是相当强大的......

于 2009-03-01T20:06:06.183 回答
0

你在 Linux 上,你不能直接获取库的源代码并破解你需要的功能吗?如果对其他人有用,您甚至可以将补丁发送给原作者,以便在以后的版本中为大家提供。

于 2009-03-01T20:08:30.000 回答
-1

mmap(),也许?

于 2009-03-01T06:27:48.787 回答