简体   繁体   中英

Send file writes to in-memory buffer (fopen something, but write to buffer, not disk)

I'd like to:

  1. redirect stdout/stderr
  2. to an in-memory buffer, rather than to disk
  3. while leaving stdout/err running as normal

I know how to use dup2 and freopen to:

  • redirect stdout/err to a file of my choosing
  • while leaving stdout/err running as normal

...but I'm not sure about item 2?

REASON: I want to post-process the data going to stdout/err (that's coming from 3rd party code), and then send it to a webserver - while leaving the application running as normal.

WHY? ... because right now when our app runs we're seeing critical data go to stdout (and err) from 3rd party code, and it's a PITA getting users to try and mess around with local logfiles. I'd rather capture "the last N bytes" into a ring buffer, post-process it, and then - iff there's a problem that the user reports - send that to server.

WHY AVOID FILES? ... because this is for code that has to run on iOS as well as desktop, and "constantly writing to a file" is something I want to avoid, since I don't want it as a file anyway. Also ... I'd have to worry about maintaining that file, proactively trimming its size, etc.

Stdout is a basic file handle, which means its a pointer.

#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;
}

By declaring stdout to point to a different file handle, this program redirects stdout. To test it, compile it as test , and then type ./test > t and ./test 2> t on the command line.

The redirected stdout pipe will still output the word test, whereas the redirected stderr pipe will not.

Since files are streams, read this section of the GNU C Library for how to create memory streams. This example creates a text buffer to dynamically resize for holding input, and redirects stdout to point to it.

#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;
}

Pay careful attention to the sections on flushing the buffers when switching between input and output in the manual.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM