2012-03-06 11 views
5

mi piacerebbe:Invia file scrive nel buffer in memoria (fopen qualcosa, ma scrivere per tamponare, non rigido)

  1. reindirizzamento output/error
  2. ad un buffer in memoria, piuttosto che su disco
  3. lasciando stdout/erro esecuzione come normale

io so come usare dup2 e freopen a:

  • reindirizzamento stdout/err in un file di mia scelta
  • lasciando stdout/err esecuzione come normale

... ma non sono sicuro circa l'articolo 2?

RAGIONE: Voglio post-elaborare i dati andando a stdout/err (che proviene da codice di terze parti), e quindi inviarlo a un server web - lasciando l'applicazione in esecuzione come di consueto.

PERCHÉ? ... perché proprio ora, quando la nostra app funziona, stiamo vedendo i dati critici andare allo stdout (ed errare) dal codice di terze parti, ed è un PITA che fa in modo che gli utenti provino a scherzare con i file di log locali. Preferisco acquisire "gli ultimi N byte" in un buffer circolare, post-elaborarlo e poi - se c'è un problema che l'utente segnala - inviarlo al server.

PERCHÉ EVITARE I FILE? ... perché questo è per codice che deve essere eseguito su iOS e desktop, e "scrivere costantemente su un file" è qualcosa che voglio evitare, dal momento che non lo voglio comunque come un file. Inoltre ... dovrei preoccuparmi di mantenere quel file, ridimensionarne in modo proattivo le dimensioni, ecc.

+1

Potresti usare un tubo. Dai un'occhiata a questa soluzione: http://stackoverflow.com/questions/955962/how-to-buffer-stdout-in-memory-and-write-it-from-a-dedicated-thread – arc

+0

Alcuni Unix o Posix hanno il http : //pubs.opengroup.org/onlinepubs/9699919799/functions/fmemopen.html function (ispirato a GNU). GNU ha anche http://linux.die.net/man/3/open_memstream forse i tuoi IOS hanno questi. –

+0

Perché le persone sembrano non avere idea di cosa sia un socket unix? Creane uno, dup2 il tuo stdin/stdout di terze parti, usa il tuo codice per post-elaborarlo, nessun disco coinvolto. – tbert

risposta

4

Stdout è un handle di file di base, che indica un puntatore.

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

Dichiarando che lo stdout punta a un diverso handle di file, questo programma reindirizza lo stdout. Per verificarlo, compilarlo come test e quindi digitare ./test > t e ./test 2> t nella riga di comando.

La pipe stdout reindirizzata emetterà ancora il test parola, mentre il pipe stderr reindirizzato non lo farà.

Poiché i file sono flussi, leggere questo section of the GNU C Library per come creare flussi di memoria. Questo esempio crea un buffer di testo per ridimensionarlo dinamicamente per contenere l'input e reindirizza lo stdout per puntarlo.

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

prestare attenzione alle sezioni sui lavaggio buffer quando si passa tra ingresso ed uscita nel manuale.

+0

Ah, grazie - sembra "flussi di memoria" era la frase magica che avevo bisogno di google. Proverò questo approccio con iOS e vedrò se funziona. Incrociamo le dita ... – Adam

+0

Suggerisco di aggiungere un 'free (bp)' alla fine. Non importa qui, ma se qualcuno sta tagliando e incollando questo in una funzione, ne avrà bisogno. –

+0

@MarkLodato Whoops! Fisso. –

Problemi correlati