我有第三方库,其中包含对指定数据执行某些计算的函数,并将结果写入由文件名指定的文件:
int manipulateAndWrite(const char *filename,
const FOO_DATA *data);
我无法更改此功能,或在我自己的功能中重新实现计算,因为我没有源。
要获得结果,我目前需要从文件中读取它们。我宁愿避免写入和读取文件,而是将结果转换为内存缓冲区。
我是否可以传递指示写入内存而不是a的文件路径 文件系统?
答案 0 :(得分:1)
是的,你有几个选择,虽然POSIX只支持下面的第一个建议。其余的都是特定于操作系统的,并且可能无法在所有POSIX系统上移植,尽管我相信它们适用于所有POSIXy系统。
您可以使用命名管道(FIFO),并在写入器函数的同时从中读取辅助线程。
因为本身没有文件,所以开销只是系统调用(写入和读取);基本上只是进程间通信的开销,没什么好担心的。为了节省资源,请使用小堆栈(使用pthread_attr_
等)创建辅助线程,因为默认堆栈大小往往很大(大约几兆字节; 2*PTHREAD_STACK_SIZE
应该足够辅助线程。)
您应确保命名管道位于安全目录中,例如,只有运行该流程的用户才能访问该目录。
在许多POSIXy系统中,您可以创建管道或套接字对,并通过/dev/fd/N
访问它,其中N
是十进制的描述符编号。 (在Linux中,/proc/self/fd/N
也有效。)这不是POSIX强制要求的,因此可能并非在所有系统上都可用,但大多数系统都支持它。
这样,本身没有实际文件,函数会写入管道或套接字。如果函数写入的数据最多为PIPE_BUF
个字节,则可以直接读取管道中的数据;否则,你需要创建一个辅助线程来同时从管道或套接字读取函数,否则写将阻塞。
在这种情况下,开销也很小。
在基于ELF的POSIXy系统(基本上全部)上,您可以插入 open()
,write()
和close()
系统调用或C库功能
(在Linux中,有两种基本方法,一种使用链接器--wrap
,另一种使用dlsym()
。两种方法都适用于这种特殊情况。这种插入函数的能力是基于ELF的方式二进制文件在运行时链接,与POSIX没有直接关系。)
首先设置插入函数,以便open()
检测文件名是否与特殊的“内存”文件匹配,并为其返回专用的描述符编号。 (您可能还需要插入其他函数,例如ftruncate()
或lseek()
,具体取决于函数的实际功能;在Linux中,您可以在ptrace
下运行二进制文件来检查它是什么系统调用实际使用。)
当使用专用描述符编号调用write()
时,您只需memcpy()
到内存缓冲区。您需要使用全局变量来描述分配的大小,使用的大小以及指向内存缓冲区的指针,并且可能准备在必要时调整大小/增大缓冲区。
当使用专用描述符编号调用close()
时,您知道内存缓冲区已完成,并且内容已准备好进行处理。
您可以在RAM文件系统上使用临时文件。虽然数据在技术上写入文件并从中读回,但操作仅涉及RAM。
您应该安排在编译时设置的默认路径,并且个别用户可以根据个人需要覆盖该路径,例如通过环境变量(YOURAPP_TMPDIR
?)。 / p>
应用程序无需尝试查找基于RAM的文件系统:这样的选择是,应该由用户决定。应用程序甚至不应该关心文件所在的文件系统类型,而应该只使用指定的目录。