C fopen gegen offen

Lesezeit: 8 Minuten

Benutzeravatar von LJM
LJM

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

Benutzeravatar von Omnifarious
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.

  1. fopen bietet Ihnen eine Pufferung von E / A, die sich als viel schneller herausstellen kann als das, was Sie tun open.
  2. 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)).
  3. EIN FILE * gibt Ihnen die Möglichkeit zu verwenden fscanf und andere stdio-Funktionen.
  4. 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

Benutzeravatar von Emil H
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

Benutzeravatar von Yogeesh HT
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

Benutzeravatar von user7116
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.

Pangs Benutzeravatar
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);

Benutzeravatar von digy
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

while (retval = close(fd), retval == -1 && ernno == EINTR) ;

  • 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?

    Benutzer11877195

    10. März um 16:37 Uhr

1426360cookie-checkC fopen gegen offen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy