C'è un modo per accoppiare due flussi (o descrittori di file) insieme in modo che la scrittura su un flusso scriva anche al secondo? (C, Linux)Scrittura simultanea su due flussi
Grazie.
C'è un modo per accoppiare due flussi (o descrittori di file) insieme in modo che la scrittura su un flusso scriva anche al secondo? (C, Linux)Scrittura simultanea su due flussi
Grazie.
L'utente laalto è corretto, ma su Linux, la funzione che si sta cercando si chiama fopencookie
. Correzione esempio di laalto per Linux si traduce in:
int my_writefn(void *cookie, const char *data, int n) {
FILE **files = (FILE **)cookie;
fwrite(data, n, 1, files[0]);
return fwrite(data, n, 1, files[1]);
}
int noop(void) { return 0; }
cookie_io_functions_t my_fns = {
(void*) noop,
(void*) my_writefn,
(void*) noop,
(void*) noop
};
FILE *files[2] = ...;
FILE *f = fopencookie((void *)files, "w", my_fns);
// ... use f as you like ...
Quando si scrive per f
, il sistema eseguirà la funzione my_writefn
passandogli i dati che è stato passato a fwrite
. Per rendere le cose più facili, si consiglia inoltre di modificare il buffer per il flusso di file da linea orientata:
setvbuf(f, NULL, _IOLBF, 0);
Che vi tamponare i dati passati al fwrite
fino a quando una nuova riga viene emesso o qualsiasi dati vengono letti da qualsiasi flusso collegato ai processi (ad es. stdin). NOTA: è necessario chiamare sevbuf
dopo fopencookie
ma prima che qualsiasi dato venga scritto nello stream.
Uso il buffering di linea perché di solito utilizzo fopencookie
per reindirizzare stderr su syslog o su un socket di rete e l'elaborazione di dati orientati alla linea è più semplice e più efficiente.
È possibile implementare qualcosa di simile alla funzionalità di tee
con boost::iostreams.
Non so se è quello che vuoi, ma 'tee' in unix fa qualcosa di simile.
Quindi il tipo "C++" viene modificato, ma viene modulato per suggerire di "costruire sul lavoro degli altri". Non è giusto ... – Roboprog
La prima cosa che mi è venuta in mente era anche "tee". Quindi, cerchiamo di combinare C e la shell con popen:
FILE * multi_out;
multi_out = popen("tee file1.out > file2.out", "w");
/* error checks, actual work here */
pclose(multi_out);
/* error checks here */
Come un bigotto Unix, ho assunto non si sta cercando questo su Windows.
Utilizzare funopen
o fwopen
e fornire la propria funzione di scrittura che scrive su più FILE*
s.
Esempio:
FILE *files[2] = ...;
FILE *f = fwopen((void *)files, my_writefn);
// ... use f as you like ...
int my_writefn(void *cookie, const char *data, int n) {
FILE **files = (FILE **)cookie;
fwrite(data, n, 1, files[0]);
return fwrite(data, n, 1, files[1]);
}
(gestione degli errori omesso.)
noti che funopen
e fwopen
sono BSD e non in Linux standard. Non sono a conoscenza se esiste un equivalente compatibile con Linux.
Apparentemente, no. Non sono nelle pagine man (almeno sul mio sistema). – jackhab
funopen è su BSD e Mac OS X. Su Linux usa fopencookie. – mark4o
@ mark4o: Grazie per le informazioni. @ Jack: Sembra che l'implementazione usando fopencookie() sarebbe abbastanza simile. Non aggiorno la mia risposta qui, ma dovresti avere alcuni suggerimenti su cui andare avanti. – laalto
Avete un esempio per C? Perché questo è rigorosamente C++;) – Skurmedel
scusa probabilmente non – stefanB