Gibt es eine Möglichkeit, zwei Streams (oder Dateideskriptoren) miteinander zu verbinden, so dass das Schreiben in einen Stream auch auf den zweiten schreibt? (C, Linux)Schreiben Sie simultanousely auf zwei Streams
Danke.
Gibt es eine Möglichkeit, zwei Streams (oder Dateideskriptoren) miteinander zu verbinden, so dass das Schreiben in einen Stream auch auf den zweiten schreibt? (C, Linux)Schreiben Sie simultanousely auf zwei Streams
Danke.
Benutzer laalto ist korrekt, aber auf Linux, die Funktion, die Sie suchen, heißt fopencookie
. Korrektur laalto Vorbild für Linux führt zu:
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 ...
Wenn Sie zu f
schreiben, wird das System Ihre my_writefn
Funktion ausführen es die Weitergabe von Daten, die auf fwrite
übergeben wurde. Um die Dinge einfacher, können Sie auch die Linie ausgerichtet werden, wollen die Pufferung für die Datei-Stream ändern:
setvbuf(f, NULL, _IOLBF, 0);
Das wird die Daten an fwrite
bis eine neue Zeile übergeben puffern ausgegeben oder eine beliebige Daten von jedem gelesen Stream an die Prozesse angehängt (zB Stdin). HINWEIS: Sie müssen sevbuf
nach fopencookie
aufrufen, aber bevor irgendwelche Daten in den Stream geschrieben werden.
Ich verwende Zeilenpufferung, weil ich normalerweise fopencookie
verwenden, um stderr auf syslog oder über einen Netzwerk-Socket umzuleiten, und die Verarbeitung von zeilenorientierten Daten ist einfacher und effizienter.
Sie können eine ähnliche Funktionalität wie tee
mit boost::iostreams implementieren.
Nicht sicher, ob es das ist, was Sie wollen, aber 'Tee' in Unix tut etwas ähnliches.
Also der "C++" Typ wird modded, aber Sie werden für den Vorschlag "auf der Arbeit von anderen bauen" heruntergestuft. Das ist nicht richtig ... – Roboprog
Das erste, was mir in den Sinn kam, war auch "Tee". So lassen Sie uns verbinden C und die Schale mit popen:
FILE * multi_out;
multi_out = popen("tee file1.out > file2.out", "w");
/* error checks, actual work here */
pclose(multi_out);
/* error checks here */
Als Unix Frömmler, ich habe angenommen, Sie sind nicht diese auf Windows versuchen.
Verwenden Sie funopen
oder fwopen
und liefern Sie Ihre eigene Schreibfunktion, die auf mehrere FILE*
s schreibt.
Beispiel:
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]);
}
(Fehlerbehandlung weggelassen.)
Beachten Sie, dass funopen
und fwopen
sind BSD und nicht in Standard-Linux. Mir ist nicht bekannt, ob es ein Linux-kompatibles Äquivalent gibt.
Anscheinend nein. Sie sind nicht in man-Seiten (zumindest auf meinem System). – jackhab
Funopen ist auf BSD und Mac OS X. Unter Linux verwenden Sie fopencookie. – mark4o
@ mark4o: Danke für die Info. @Jack: Scheint so, als wäre die Implementierung mit fopencookie() ziemlich ähnlich. Ich aktualisiere meine Antwort hier nicht, aber Sie sollten einige Hinweise haben, mit denen Sie fortfahren können. – laalto
Haben Sie ein Beispiel für C? Denn das ist streng genommen C++;) – Skurmedel
Entschuldigung wahrscheinlich nicht – stefanB