【问题标题】:Send file writes to in-memory buffer (fopen something, but write to buffer, not disk)将文件写入发送到内存缓冲区(fopen,但写入缓冲区,而不是磁盘)
【发布时间】:2012-03-06 20:18:24
【问题描述】:

我想:

  1. 重定向标准输出/标准错误
  2. 到内存缓冲区,而不是磁盘
  3. 同时让 stdout/err 正常运行

我知道如何使用 dup2 和 freopen 来:

  • 将 stdout/err 重定向到我选择的文件
  • 同时让 stdout/err 正常运行

...但我不确定第 2 项?

原因:我想对进入 stdout/err 的数据进行后处理(来自第 3 方代码),然后将其发送到网络服务器 - 同时让应用程序正常运行。

为什么? ...因为现在当我们的应用程序运行时,我们看到关键数据从 3rd 方代码进入标准输出(和错误),这是一个让用户尝试处理本地日志文件的 PITA。我宁愿将“最后 N 个字节”捕获到环形缓冲区中,对其进行后处理,然后 - 如果用户报告存在问题 - 将其发送到服务器。

为什么要避免文件? ...因为这是用于必须在 iOS 和桌面上运行的代码,并且“不断写入文件”是我想要避免的,因为我不希望它作为文件。另外...我不得不担心维护该文件,主动修剪其大小等。

【问题讨论】:

  • 你可以使用管道。查看此解决方案:stackoverflow.com/questions/955962/…
  • 一些 Unix 或 Posix 具有 pubs.opengroup.org/onlinepubs/9699919799/functions/… 函数(受 GNU 启发)。 GNU 也有 linux.die.net/man/3/open_memstream 或许你的 IOS 有这些。
  • 为什么人们似乎不知道 unix socket 是什么?创建一个,将您的第 3 方标准输入/标准输出复制到它,使用您的代码对其进行后处理,不涉及磁盘。
  • @arc 我喜欢使用管道的想法,但根据那个问题,管道可能会阻塞,性能可能会急剧下降。不确定,但我将首先尝试使用内存流,这似乎更接近 C 想要我做的事情。
  • @Adam 我也需要这个。你找到解决办法了吗?

标签: c ios


【解决方案1】:

Stdout 是一个基本的文件句柄,这意味着它是一个指针。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv);

int main (argc,argv)
int argc;
char **argv;
{
    stdout = &(*stderr);
    fprintf(stdout, "test");
    return 0;
}

通过声明 stdout 指向不同的文件句柄,此程序重定向 stdout。要对其进行测试,请将其编译为test,然后在命令行中键入./test &gt; t 和./test 2&gt; t。

重定向的 stdout 管道仍将输出单词 test,而重定向的 stderr 管道不会。

由于文件是流,请阅读section of the GNU C Library 了解如何创建内存流。此示例创建一个文本缓冲区以动态调整大小以保存输入,并重定向 stdout 以指向它。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv);

int main (argc,argv)
int argc;
char **argv;
{
    char *bp;
    size_t size;
    FILE *stream;

    stream = open_memstream (&bp, &size);
    stdout = &(*stream);
    fprintf(stdout, "test");
    fflush(stdout);
    fprintf(stderr, "buf = %s, size = %d\n", bp, size);
    fclose (stream);
    free(bp);
    return 0;
}

请注意手册中有关在输入和输出之间切换时刷新缓冲区的部分。

【讨论】:

  • 啊,谢谢 - 似乎“记忆流”是我需要用谷歌搜索的神奇短语。我将在 iOS 上尝试这种方法,看看它是否有效。手指交叉...
  • 我建议在末尾添加free(bp)。在这里没关系,但如果有人将其剪切并粘贴到函数中,他们将需要它。
  • @MarkLodato 哎呀!固定。
  • 我从未完成过测试,但无论如何我都将其标记为已接受 - 我觉得它是正确的,Spencer 应该得到认可。
猜你喜欢
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多