Schließen Sie einen FILE-Zeiger, ohne den zugrunde liegenden Dateideskriptor zu schließen
Lesezeit: 2 Minuten
Durch die Nutzung fdopen(), fileno() Es ist möglich, Streams mit vorhandenen Dateideskriptoren zu öffnen. Der richtige Weg, eine Datei zu schließen, nachdem Sie sie mit einem Stream geöffnet haben, ist jedoch fclose() das FILE Zeiger. Wie kann man den Stream schließen, aber den offenen Dateideskriptor beibehalten?
Dieses Verhalten ähnelt dem Anrufen fflush() und dann fileno()und dann nie mit der FILE Zeiger wieder, außer beim Schließen. Eine zusätzliche Sorge ist, dass, wenn Sie dann fdopen() Auch hier gibt es jetzt mehrere FILE Zeiger, und Sie können nur einen davon schließen.
bdonlan
Wenn Sie auf einem POSIXy-System sind (was ich vermute, da Sie es haben fileno()), können Sie verwenden dup() um den Dateideskriptor zu klonen:
int newfd = dup(fileno(stream));
fclose(stream);
Oder Sie können übergeben fdopen() ein doppelter Dateideskriptor:
FILE *stream = fdopen(dup(fd), "r");
In jedem Fall wird die andere Kopie des fd nicht mit dem geschlossen FILE *. Beachten Sie jedoch den Positionszeiger ist geteilt, seien Sie also vorsichtig, wenn Sie beide gleichzeitig verwenden. Auch irgendwelche fcntl() Sperren auf der ursprünglichen fd Wille freigegeben werden, wenn Sie die Kopie schließen.
Windows und andere Plattformen unterstützen fileno()! Ich kann nicht glauben, dass ich nicht an diese Lösung von dup() gedacht habe, sehr elegant und offensichtlich
– Matt Tischler
21. Oktober 2009 um 22:17 Uhr
Müssen Sie nicht auch die neue fd zurück auf die ursprüngliche fd duup2() und dann die neue fd schließen(), damit alles wieder so ist, wie es vorher war, außer dass der Dateistream geschlossen wird? 😀 Was bedeutet, dass Sie oldfd = fileno(stream) benötigen, bevor Sie fclose() ausführen.
– Jonathan Leffler
21. Oktober 2009 um 22:17 Uhr
Jonathan, do zu tun ist rassig in Multithread-Anwendungen. Es ist besser zu dup bevor Sie die fd geben fdopen So können Sie sicher sein, dass es niemals Ihr Original berührt.
– bdonlan
21. Oktober 2009 um 22:35 Uhr
@bdonlan, erkläre: Ich sehe nicht, wie es rassig ist
– Matt Tischler
22. Oktober 2009 um 4:09 Uhr
Thread A: schließen (42); Thread B: open(…) (gibt 42 zurück) Thread A: dup2(42, 54); Jetzt wurde der fd von Thread B geschlossen und durch den Thread A ersetzt, mit dem er gearbeitet hat.
– bdonlan
22. Oktober 2009 um 4:20 Uhr
Wenn alles andere fehlschlägt, könnte dup(2) helfen.
12686500cookie-checkSchließen Sie einen FILE-Zeiger, ohne den zugrunde liegenden Dateideskriptor zu schließenyes