C 我可以将写入磁盘的函数调整为写入内存吗

C 我可以将写入磁盘的函数调整为写入内存吗,c,posix,C,Posix,我有一个第三方库,它有一个函数,可以对指定的数据进行一些计算,并将结果写入由文件名指定的文件: int manipulateAndWrite(const char *filename, const FOO_DATA *data); 我无法更改此函数,或在自己的函数中重新实现计算,因为我没有源代码 要获得结果,我当前需要从文件中读取它们。我更愿意避免对文件的写入和读取,而是将结果获取到内存缓冲区中 我是否可以传递一个指示写入内存的文件路径,而不是 文

我有一个第三方库,它有一个函数,可以对指定的数据进行一些计算,并将结果写入由文件名指定的文件:

int manipulateAndWrite(const char *filename,
                       const FOO_DATA *data);
无法更改此函数,或在自己的函数中重新实现计算,因为我没有源代码

要获得结果,我当前需要从文件中读取它们。我更愿意避免对文件的写入和读取,而是将结果获取到内存缓冲区中

我是否可以传递一个指示写入内存的文件路径,而不是
文件系统?

您无法使用该库函数。了解如何写入内存中的文件:

是的,虽然POSIX只支持下面的第一个建议,但您有几个选项。其余部分是特定于操作系统的,可能无法在所有POSIX系统上移植,尽管我相信它们可以在所有POSIXy系统上工作。

  • 您可以使用命名管道(FIFO),并让一个辅助线程从中并发地读取到writer函数

    因为没有文件本身,开销只是系统调用(写和读);基本上只是进程间通信的开销,没什么好担心的。为了节省资源,请使用小堆栈创建辅助线程(使用
    pthread\u attr\u
    等),因为默认堆栈大小往往很大(大约为几兆字节;
    2*pthread\u stack\u size
    对于辅助线程来说应该足够大)

    您应该确保命名管道位于安全目录中,例如,只有运行流程的用户才能访问。

  • 在许多POSIXy系统中,您可以创建管道或套接字对,并通过
    /dev/fd/N
    访问它,其中
    N
    是十进制的描述符编号。(在Linux中,
    /proc/self/fd/N
    也起作用。)POSIX没有强制要求这样做,因此可能无法在所有系统上使用,但大多数系统都支持它

    这样,就没有实际的文件本身,函数将写入管道或套接字。如果函数写入的数据最多为
    PIPE\u BUF
    字节,您只需在之后从管道读取数据即可;否则,您确实需要创建一个helper线程来从管道或套接字同时读取函数,否则写操作将被阻塞

    在这种情况下,开销也是最小的。

  • 在基于ELF的POSIXy系统(基本上全部)上,可以插入
    open()
    write()
    、和
    close()
    系统调用或C库函数

    (在Linux中,有两种基本方法,一种使用链接器
    --wrap
    ,另一种使用
    dlsym()
    。这两种方法都适用于这种特殊情况。插入函数的能力取决于ELF二进制文件在运行时的链接方式,与POSIX没有直接关系。)

    首先设置插入函数,以便
    open()
    检测文件名是否与特殊的“内存中”文件匹配,并为其返回专用描述符编号。(您可能还需要插入其他函数,如
    ftruncate()
    lseek()
    ,具体取决于函数的实际功能;在Linux中,您可以在
    ptrace
    下运行二进制文件,以检查它实际使用的系统调用。)

    当使用专用描述符编号调用
    write()
    时,只需
    memcpy()。您需要使用全局变量来描述分配的大小、使用的大小和指向内存缓冲区的指针,并且可能准备在必要时调整/增加缓冲区的大小

    当使用专用描述符编号调用
    close()
    时,您知道内存缓冲区已完成,内容已准备好进行处理。

  • 您可以在RAM文件系统上使用临时文件。虽然从技术上讲,数据被写入文件并从中读取,但操作仅涉及RAM

    您应该安排在编译时设置一个默认路径,并让个人用户能够根据个人需要覆盖该路径,例如通过环境变量(
    YOURAPP\u TMPDIR
    ?)

    应用程序不需要尝试寻找基于RAM的文件系统:这样的选择取决于用户,也应该取决于用户。应用程序甚至不应该关心文件位于什么类型的文件系统上,而应该只使用指定的目录


是的,使用RAM驱动器路径。相关:Linux和Windows上存在哪些操作系统解决方案,用于创建RAM磁盘,并从该RAM磁盘传递文件路径。它不会写入磁盘。请注意,如果文件很小,如果立即重新读取并删除,写入临时目录根本不会写入磁盘。此第三方库的设计已损坏。允许写入
文件*
对象会给你更多的选择。@Jean-Françoisfare是真的,但在Debian和derivates上,你可以很容易地读/写/dev/shmt。这个链接没有帮助,因为它是不相关的。他要求选项,这个问题用c和POSIX标记。链接如何不相关?因为OP在界面中没有一个
文件
对象作为开始,因此这是一个选项。使用他的库函数的替代方法。这不是我的库函数。问题是,我需要捕获此函数正在执行的其他数据操作,而不会受到影响磁盘的惩罚。