Gibt es einen Grund (außer syntaktischen), den Sie verwenden möchten
FILE *fdopen(int fd, const char *mode);
oder
FILE *fopen(const char *path, const char *mode);
Anstatt von
int open(const char *pathname, int flags, mode_t mode);
bei der Verwendung von C in einer Linux-Umgebung?
Meinten Sie fdopen und open oder fopen und open?
– Benutzer7116
1. November 2009 um 21:53 Uhr
Meinst du nicht fopen, nicht fdopen?
– Allmächtig
1. November 2009 um 21:53 Uhr
fopen ist Teil der Standard-C-Bibliothek, open ist nicht. Verwenden fopen beim Schreiben von portablem Code.
– Aziz
1. November 2009 um 21:53 Uhr
Ja, ich meinte fopen. Ich habe es gerade aktualisiert, aber ich denke, das gleiche Prinzip gilt.
– LJM
1. November 2009 um 21:54 Uhr
@ Aziz, open ist jedoch eine POSIX-Funktion.
– Traumlax
1. November 2009 um 21:55 Uhr
Allmächtig
Erstens gibt es keinen besonders guten Grund für die Verwendung fdopen wenn fopen ist eine Option u open ist die andere mögliche Wahl. Du hättest nicht verwenden sollen open um die Datei überhaupt zu öffnen, wenn Sie möchten a FILE *. Also inklusive fdopen in dieser Liste ist falsch und verwirrend, weil es den anderen nicht sehr ähnlich ist. Ich werde es jetzt ignorieren, da die wichtige Unterscheidung hier zwischen einem C-Standard besteht FILE * und einen betriebssystemspezifischen Dateideskriptor.
Es gibt vier Hauptgründe für die Verwendung fopen Anstatt von open.
fopen bietet Ihnen eine Pufferung von E / A, die sich als viel schneller herausstellen kann als das, was Sie tun open.
fopen übersetzt das Zeilenende, wenn die Datei nicht im Binärmodus geöffnet ist, was sehr hilfreich sein kann, wenn Ihr Programm jemals in eine Nicht-Unix-Umgebung portiert wird (obwohl die Welt anscheinend nur auf LF konvergiert (außer textbasierte IETF-Netzwerke). Protokolle wie SMTP und HTTP und dergleichen)).
EIN FILE * gibt Ihnen die Möglichkeit zu verwenden fscanf und andere stdio-Funktionen.
Ihr Code muss möglicherweise eines Tages auf eine andere Plattform portiert werden, die nur ANSI C unterstützt und die nicht unterstützt open Funktion.
Meiner Meinung nach steht Ihnen die Übersetzung des Zeilenendes öfter im Weg, als dass sie Ihnen hilft, und das Parsen von fscanf ist so schwach, dass Sie es unweigerlich zugunsten von etwas Nützlicherem wegwerfen.
Und die meisten Plattformen, die C unterstützen, haben eine open Funktion.
Bleibt die Pufferfrage. An Orten, an denen Sie eine Datei hauptsächlich sequentiell lesen oder schreiben, ist die Pufferunterstützung wirklich hilfreich und eine große Geschwindigkeitsverbesserung. Aber es kann zu einigen interessanten Problemen führen, bei denen Daten nicht in der Datei landen, wenn Sie es erwarten. Sie müssen sich daran erinnern fclose oder fflush zu den passenden Zeiten.
Wenn Sie suchen (aka fsetpos oder fseek die zweite davon ist etwas kniffliger in einer standardkonformen Weise zu verwenden), lässt die Nützlichkeit der Pufferung schnell nach.
Natürlich bin ich der Meinung, dass ich dazu neige, viel mit Sockets zu arbeiten, und dass Sie wirklich nicht blockierende E / A machen möchten (was FILE * unterstützt überhaupt nicht auf vernünftige Weise) ohne jegliche Pufferung und haben oft komplexe Parsing-Anforderungen, die meine Wahrnehmung wirklich färben.
Ich werde Ihre Erfahrungen nicht in Frage stellen, aber ich würde gerne hören, wie Sie dies ein wenig erläutern. Bei welchen Anwendungen stört Ihrer Meinung nach die eingebaute Pufferung? Was genau ist das Problem?
– Emil H
1. November 2009 um 22:04 Uhr
Letzten Absatz nicht gesehen. Gültiger Punkt, IMHO. Soweit ich das beurteilen kann, ging es bei der Frage jedoch um Datei-IO.
– Emil H
1. November 2009 um 22:06 Uhr
Um zu klären, wann die Pufferung im Weg steht. Es ist, wenn Sie seek verwenden. Das Folgende wird mit einem beliebigen Befehl gelesen (fgets, fgetc, fscanf, fread) liest immer die gesamte Größe des Puffers (4K, 8K oder was auch immer Sie einstellen). Durch die Verwendung der direkten I/O können Sie dies vermeiden. In diesem Fall ist es noch besser zu verwenden pread anstelle eines Seek/Read-Paares (1 Syscall statt 2).
– Patrick Schlüter
5. Mai 2010 um 13:16 Uhr
Handhabung unterbrochen read() und write() Aufrufe sind ein bequemer fünfter Grund, die libc-Funktionsfamilie zu verwenden.
– nccc
26. August 2012 um 21:54 Uhr
@m-ric: Nun, das ist eine etwas unabhängige Frage, aber ja. Alle Plattformen, die unterstützen ioctl unterstützt auch die fileno Anruf, der dauert FILE * und gibt eine Zahl zurück, die in einem verwendet werden kann ioctl Anruf. Seien Sie jedoch vorsichtig. FILE * Verwandte Anrufe können überraschend mit der Verwendung interagieren ioctl um etwas am zugrunde liegenden Dateideskriptor zu ändern.
– Allmächtig
28. September 2012 um 15:53 Uhr
Emil h
open() ist ein Low-Level-Os-Aufruf. fdopen() konvertiert einen Dateideskriptor auf Betriebssystemebene in die FILE-Abstraktion auf höherer Ebene der Sprache C. fopen() Anrufe open() im Hintergrund und gibt Ihnen direkt einen FILE-Zeiger.
Die Verwendung von FILE-Objekten anstelle von rohen Dateideskriptoren hat mehrere Vorteile, darunter eine einfachere Verwendung, aber auch andere technische Vorteile wie eingebaute Pufferung. Vor allem die Pufferung führt in der Regel zu einem deutlichen Performance-Vorteil.
Gibt es Nachteile bei der Verwendung der gepufferten ‘f …’-Versionen von open?
– LJM
1. November 2009 um 21:58 Uhr
@L. Moser, ja, wenn Sie die Daten bereits puffern und daher der zusätzliche Puffer unnötigen Kopier- und Speicheraufwand hinzufügt.
– Michael Aaron Safyan
2. November 2009 um 1:41 Uhr
eigentlich gibt es noch andere nachteile. fopen() bietet nicht das gleiche Maß an Kontrolle beim Öffnen von Dateien, z. B. Erstellungsberechtigungen, Freigabemodi und mehr. typisch open() und Varianten bieten viel mehr Kontrolle, nahe an dem, was das Betriebssystem tatsächlich bietet
– Matt Tischler
7. November 2009 um 11:54 Uhr
Es gibt auch die Extremfälle, wo Sie mmap die Datei und nehmen Sie Änderungen mit normalem I/O vor (so unglaublich es auch klingt, wir tun das tatsächlich in unserem Projekt und aus wirklich guten Gründen), Pufferung wäre im Weg.
– Patrick Schlüter
5. Mai 2010 um 13:20 Uhr
Möglicherweise möchten Sie auch andere Systemfunktionen verwenden, z. B. die Verwendung von open() zum Vorabladen von Dateien in den Seitencache über readahead(). Ich denke, die Faustregel lautet “verwenden Sie fopen, es sei denn, Sie brauchen unbedingt open()”, mit open() können Sie tatsächlich ausgefallene Dinge tun (setzen/nicht setzen von O_ATIME und ähnliches).
– Tomás Pruzina
14. Mai 2013 um 4:11 Uhr
Yogeesh HT
fopen vs. open in C
1) fopen ist ein Bibliotheksfunktion während open ist ein Systemaufruf.
2) fopen bietet gepufferte IO was im Vergleich schneller ist open welches ist nicht gepuffert.
3) fopen ist tragbar während open nicht tragbar (open ist umgebungsspezifisch).
4) fopen gibt einen Zeiger auf a zurück FILE-Struktur (FILE *); open gibt eine Ganzzahl zurück, die die Datei identifiziert.
5) A FILE * gibt Ihnen die Möglichkeit zu verwenden fscanf und andere stdio-Funktionen.
open ist ein POSIX-Standard, also ziemlich portabel
– osven
5. Oktober 2017 um 13:22 Uhr
fopen() ist nicht async-signalsicher (keines der gepufferten io ist), daher sollte es nicht in einem Signalhandler verwendet werden – oder in einer Funktion, die von ihm aufgerufen werden kann, und mit Vorsicht behandelt werden, wenn es in Funktionen verwendet wird, die asynchrone Threads verwenden. Verwenden open() fügt Komplexität hinzu und vermisst das gepufferte IO, …
– Simon Sobisch
16. Juni 2021 um 18:47 Uhr
@osvein Nicht mehr wirklich tragbar. Funktioniert gut mit Linux, ist aber jetzt in Windows veraltet. Sie sollten jetzt _open, _close verwenden. So eine Kleinigkeit. Ich denke, die Header, die unter Linux und Windows benötigt werden, sind ebenfalls unterschiedlich. Ich denke, es wäre schwierig, portablen Code ohne einige Zeilen “#if OS_LINUX” zu schreiben.
– Jiminion
2. Mai um 14:40 Uhr
Benutzer7116
Es sei denn, Sie gehören zu den 0,1 % der Anwendungen, die verwendet werden open ein tatsächlicher Leistungsvorteil ist, gibt es wirklich keinen triftigen Grund, es nicht zu verwenden fopen. So weit wie fdopen Wenn Sie nicht mit Dateideskriptoren spielen, brauchen Sie diesen Aufruf nicht.
Bleiben bei fopen und seine Methodenfamilie (fwrite, fread, fprintf, et al) und Sie werden sehr zufrieden sein. Ebenso wichtig ist, dass andere Programmierer mit Ihrem Code zufrieden sind.
Wenn Sie eine haben FILE *können Sie Funktionen wie verwenden fscanf, fprintf und fgets usw. Wenn Sie nur den Dateideskriptor haben, haben Sie begrenzte (aber wahrscheinlich schnellere) Eingabe- und Ausgaberoutinen read, write usw.
Stich
open() ist ein Systemaufruf und spezifisch für Unix-basierte Systeme und gibt einen Dateideskriptor zurück. Sie können mit in einen Dateideskriptor schreiben write() das ist ein weiterer Systemaufruf. fopen() ist ein ANSI-C-Funktionsaufruf, der einen Dateizeiger zurückgibt und auf andere Betriebssysteme portierbar ist. Wir können mit in einen Dateizeiger schreiben fprintf.
Unter Unix:
Sie können einen Dateizeiger aus dem Dateideskriptor erhalten, indem Sie Folgendes verwenden:
fP = fdopen(fD, "a");
Sie können einen Dateideskriptor vom Dateizeiger erhalten mit:
fD = fileno (fP);
digi
Die Verwendung von Open, Read, Write bedeutet, dass Sie sich um Signalinteraptionen kümmern müssen.
Wenn der Aufruf von einem Signalhandler unterbrochen wurde, geben die Funktionen -1 zurück und setzen errno auf EINTR.
Der richtige Weg, eine Datei zu schließen, wäre also
Zum close, dies hängt vom Betriebssystem ab. Es ist falsch, die Schleife unter Linux, AIX und einigen anderen Betriebssystemen auszuführen.
– Strkat
30. Dezember 2013 um 22:29 Uhr
Darüber hinaus leiden Lese- und Schreibvorgänge unter demselben Problem, dh sie können durch ein Signal unterbrochen werden, bevor die Ein-/Ausgabe vollständig verarbeitet wurde, und der Programmierer muss mit solchen Situationen umgehen, während fread und fwrite Signalunterbrechungen gut handhaben.
– Marcelo
5. Juli 2018 um 20:55 Uhr
Ich habe das viel zu oft gesehen, aber nie einen guten Grund, warum dies jemals ein Problem sein würde. Vielleicht könnten Sie ein Beispiel geben, wo es tatsächlich eine Notwendigkeit wäre, es nicht zu verwenden SA_RESTART in Ihrem Signal-Handler und lassen Sie stattdessen Systemaufrufe zurückgeben EINTR?
Meinten Sie
fdopen
undopen
oderfopen
undopen
?– Benutzer7116
1. November 2009 um 21:53 Uhr
Meinst du nicht fopen, nicht fdopen?
– Allmächtig
1. November 2009 um 21:53 Uhr
fopen
ist Teil der Standard-C-Bibliothek,open
ist nicht. Verwendenfopen
beim Schreiben von portablem Code.– Aziz
1. November 2009 um 21:53 Uhr
Ja, ich meinte fopen. Ich habe es gerade aktualisiert, aber ich denke, das gleiche Prinzip gilt.
– LJM
1. November 2009 um 21:54 Uhr
@ Aziz,
open
ist jedoch eine POSIX-Funktion.– Traumlax
1. November 2009 um 21:55 Uhr