当函数想要传递FILE *时,避免使用临时文件

时间:2011-10-07 15:28:28

标签: c graphviz boost-graph

我目前使用C ++使用boost :: graph进行一些与图形相关的计算。 boost :: graph可以将其图形输出为点文件,我使用std :: stringstream来捕获输出点文件。因此,点文件的内容驻留在内存中。

我想使用点文件来显示图表(尽可能快)。因此,我想生成点文件,生成一个svg文件并将其打印到一些画布上。我想避免使用临时文件,因为图形应该很小并且无论如何都可以使用内存。

然而,graphviz libgraph只有函数extern Agraph_t *agread(FILE *);,我能想象的唯一方法就是在文件句柄struct __FILE中进行破解,这实际上是不可移植的。

你如何让一个库将你的内存内容读作Unix / linux中的文件?

我刚刚发现GraphViz中的libcgraph允许在这里输入一个重载版本,但到目前为止,文档并没有指向一些有用的地方。

4 个答案:

答案 0 :(得分:4)

嗯,它可以说是API中的一个错误,但这是一个想法。这假设agread()函数将以二进制数据的形式读取文件。

请注意,我不熟悉您正在使用的API,但我希望这可能会有用。

  1. 使用mmap()将文件映射到内存。
  2. 使用该内存区域进行图形构建。
  3. 当需要调用agread()时,如果没有关闭描述符,请将该文件描述符打开到FILE *结构(fopen()fdopen()中。) / LI>
  4. 传递FILE *结构。
  5. 修改:或者,忽略我的回答并使用fmemopen()来电。它可能正是您所需要的。我不想删除我的答案,以防有人正在撰写回复: - )。

答案 1 :(得分:3)

您可以使用pipe()创建管道,将数据写入输入端并使用fdopen()将输出文件描述符转换为适合传递到agread()的文件句柄。

但是,只有当您确定数据is less than PIPE_BUF bytes时,这才有效。否则写入可能永远阻止,因为没有任何东西从另一端读取。

通常,使用临时文件更容易,更可靠。只需使用tmpfile()获取文件句柄,将数据写入其中,快退并将其传递给agread()

fh = tmpfile();
fputs( data, fh );
rewind( fh );
graph = agread( fh );
fclose( fh );

(当然,你应该检查错误,我不是为了简洁起见。)

答案 2 :(得分:1)

如果您愿意使用GNU libc扩展,则可以将C字符串打开为FILE*;文档位于http://www.gnu.org/s/libc/manual/html_node/String-Streams.html

答案 3 :(得分:0)

在Windows上,您可以使用fopen打开命名管道。

FILE* f = fopen("\\\\.\\Pipe\\<pipe name>", "rb");

因此,您可以在单独的线程中创建管道,在该线程中推送数据,并且agread将从中读取而无需临时文件。