2012-03-06 25 views
5

me gustaría:Enviar archivo escribe en el búfer en memoria (fopen algo, pero escribir para amortiguar, no disco)

  1. redirección de stdout/stderr
  2. a un búfer en memoria, en lugar que en el disco
  3. dejando stdout/err funcionando con normalidad

sé cómo utilizar dup2 y freopen a:

  • redirección de stdout/err a un archivo de mi elección
  • dejando stdout/err funcionando con normalidad

... pero no estoy seguro sobre el tema 2?

MOTIVO: Deseo procesar los datos que van a stdout/err (que provienen del código de un tercero), y luego enviarlos a un servidor web, dejando la aplicación funcionando normalmente.

¿POR QUÉ? ... porque en este momento, cuando se ejecuta nuestra aplicación, vemos que los datos críticos pasan a stdout (y err) de código de terceros, y es un PITA que hace que los usuarios intenten meterse con los archivos de registro locales. Prefiero capturar "los últimos N bytes" en un búfer de anillo, postprocesarlo, y luego, si hay un problema que informa el usuario, enviarlo al servidor.

¿POR QUÉ EVITAR ARCHIVOS? ... porque se trata de un código que debe ejecutarse en iOS y en el escritorio, y "escribir constantemente en un archivo" es algo que quiero evitar, ya que no lo quiero como un archivo de todos modos. Además ... Tendría que preocuparme por mantener ese archivo, recortar proactivamente su tamaño, etc.

+1

Puede usar un tubo. Vea esta solución: http://stackoverflow.com/questions/955962/how-to-buffer-stdout-in-memory-and-write-it-from-a -dedicated-thread – arc

+0

Algunos Unixes o Posix tienen el http : //pubs.opengroup.org/onlinepubs/9699919799/functions/fmemopen.html función (inspirada en GNU). GNU también tiene http://linux.die.net/man/3/open_memstream quizás su IOS tenga estos. –

+0

¿Por qué la gente parece no tener idea de qué es un socket unix? Cree uno, duplique su stdin/stdout de terceros, utilice su código para postprocesarlo, sin disco. – tbert

Respuesta

4

Stdout es un controlador de archivo básico, lo que significa que es un puntero.

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

Al declarar que stdout apunte a un identificador de archivo diferente, este programa redirige a stdout. Para probarlo, compílelo como test, y luego escriba ./test > t y ./test 2> t en la línea de comando.

La tubería stdout redirigida seguirá emitiendo la palabra prueba, mientras que la tubería stderr redirigida no lo hará.

Como los archivos son transmisiones, lea esto section of the GNU C Library para saber cómo crear flujos de memoria. Este ejemplo crea un búfer de texto para cambiar el tamaño dinámicamente para mantener la entrada, y redirige a stdout para que apunte a él.

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

prestar especial atención a las secciones en el lavado de los tampones cuando se cambia entre la entrada y salida en el manual.

+0

Ah, gracias - parece que las "secuencias de memoria" eran la frase mágica que necesitaba para googlear. Probaré este enfoque con iOS y veré si funciona. Dedos cruzados ... – Adam

+0

Sugiero agregar un 'libre (bp)' al final. No importa aquí, pero si alguien está cortando y pegando esto en una función, lo necesitarán. –

+0

@MarkLodato ¡Vaya! Fijo. –

Cuestiones relacionadas