Die-Handschelle

Mythos: Explained by a Retired Microsoft Engineer – fopen is Magic! – Find Out What You’ve Been Missing All These Years!

  • AFD (12)
  • Bündnis 90/Die Grünen (1)
  • CDU (2)
  • CSU (2)
  • Die Linke (1)
  • FDP (5)
  • SED (1)
  • SPD (1)

Mythos: Explained by a Retired Microsoft Engineer – fopen is Magic! – Find Out What You’ve Been Missing All These Years!

Mythos: Explained by a Retired Microsoft Engineer – YouTube Kanal-Aufrufe 0 Kanal https://www.youtube.com/channel/UCNzszbnvQeFzObW0ghk0Ckw 🔗 https://www.youtube.com/watch?v=XAzUoizwnXM 🤖 Zusammenfassung Der Text erklärt, warum die C-Funktion `fopen` weit mehr ist als ein simpler Dateiöffner: Sie verkörpert die Unix-Philosophie „Alles ist ein Bytestrom“. Hinter dem kleinen Interface können Dateien, Tastaturen, Terminals, Pipes, Geräte wie `/dev/null`, `/dev/zero`, `/dev/urandom`, `/dev/tty` oder…

, , ,

Mythos: Explained by a Retired Microsoft Engineer – YouTube

Kanal-Aufrufe 0
Kanal https://www.youtube.com/channel/UCNzszbnvQeFzObW0ghk0Ckw

fopen is Magic! - Find Out What You've Been Missing All These Years!

🔗 https://www.youtube.com/watch?v=XAzUoizwnXM

🤖 Zusammenfassung

Der Text erklärt, warum die C-Funktion `fopen` weit mehr ist als ein simpler Dateiöffner: Sie verkörpert die Unix-Philosophie „Alles ist ein Bytestrom“. Hinter dem kleinen Interface können Dateien, Tastaturen, Terminals, Pipes, Geräte wie `/dev/null`, `/dev/zero`, `/dev/urandom`, `/dev/tty` oder Pseudodateien unter `/proc` stecken – ohne dass der Anwendercode das bemerkt. Zudem werden die drei Standardkanäle stdin (0), stdout (1) und stderr (2) erläutert, deren Umleitung durch die Shell Pipelines erst ermöglicht. Der `FILE`-Pointer ist dabei ein gepufferter Wrapper um den Unix-Dateideskriptor; diese Pufferung spart teure Systemaufrufe, erklärt aber auch scheinbar merkwürdiges Verhalten von `printf` oder `fork`. Die Modusstrings (`r`, `w`, `a` etc.) werden vorgestellt, wobei Anfügemodus durch Kernel-Unterstützung (`O_APPEND`) Race Conditions vermeidet. Als Empfehlung gilt: Funktionen sollten `FILE*`-Zeiger statt Dateinamen erhalten, um Eingaben flexibel aus Dateien, Pipes, Geräten oder Speicherströmen lesen zu können. Zugehörige APIs wie `fdopen`, `fileno`, `freopen` und `popen` runden das Bild ab. Der Sprecher schließt mit einem üblichen Appell zu Abonnements und Likes.

Summary created by "LinkBuster-KI HAL8999 – Status READY!!"

📜 Transkript

Heute werden wir über eine der langweiligsten Funktionen der gesamten C-Laufzeitumgebung sprechen, und ich werde versuchen, Sie davon zu überzeugen, dass sich hinter fünf kleinen Buchstaben eine der wichtigsten Ideen der Informatik verbirgt. Ich spreche von F offen. Wenn man C auf die übliche Weise lernt, ist F open wahrscheinlich ungefähr zu dem Zeitpunkt entstanden, als dem Lehrbuch die interessanten Dinge über Arrays ausgingen. Du hast ein kleines Programm geschrieben, das data.text öffnete, ein paar Zeilen las, einige Wörter zählte, ein bisschen Spaß hatte, ein paar Mal lachte, die Datei schloss und sich dann den Zeigern zuwandte, wo das eigentliche Blutvergießen begann. Und du bist wahrscheinlich immer noch traumatisiert, weil du F offen fast komplett vergessen hast. Und weil F open auf den ersten Blick so einfach ist, ordnen die meisten Programmierer es gedanklich der Grundausstattung zu. Es öffnet die Datei. Es gibt etwas zurück. Du übergibst das Ding an printf oder fgets, und wenn du fertig bist, rufst du F close auf, Fall abgeschlossen. Aber nicht ganz. Denn hinter dieser winzigen Funktion verbirgt sich eine der grundlegendsten Ideen von Unix, einer der Gründe, warum C zu einer so praktischen Systemsprache wurde, und einer der Gründe, warum kleine Programme, die vor 50 Jahren geschrieben wurden, auch heute noch so schön zusammengesetzt werden können. F open ist einfach, weil die Schnittstelle klein ist, aber magisch, weil das, was sich hinter dieser Schnittstelle verbirgt, möglicherweise gar keine Datei auf der Festplatte ist. Es könnte an Ihrer Tastatur liegen. Es könnte an Ihrem Terminal liegen. Es könnte sich um ein Rohr aus einem anderen Prozess handeln. Es könnte sich um eine serielle Schnittstelle handeln. Es könnte sich um den Bit-Bucket bei dev/null handeln oder um einen unendlichen Strom von Null-Bytes von dev zero oder um zufällige Daten aus dem Kernel. Oder eine Pseudodatei im Prozess, die im normalen Sinne nicht auf der Festplatte existiert , sondern tatsächlich vom Betriebssystem während des Lesens synthetisiert wird. Und mit ein paar ähnlichen Tricks könnte es sich sogar um die Ausgabe eines anderen Programms, einer Netzwerkverbindung oder eines vollständig im Speicher gespeicherten Datenstroms handeln. Und das Schöne daran ist, dass Ihr Code das oft gar nicht wissen muss. Und genau das ist der Trick. Das ist die ganze Magie von Unix in einem Satz. Man nehme völlig unterschiedliche Dinge, lasse sie so aussehen, als wären sie Byte-Stränge, und plötzlich können winzige, einfache Werkzeuge absurd leistungsstarke Dinge vollbringen. Gehen wir also ganz zurück zum Anfang, oder zumindest so nah an den Anfang, dass der Bart dunkler und die Anschlüsse lauter werden. In letzter Zeit verbringe ich etwa die Hälfte meiner Arbeitstage damit, unter dem ursprünglichen BSD Unix auf meinem PDP-11 zu arbeiten. Und alles, was wir hier machen werden, funktioniert tatsächlich auf jedem POSIX-kompatiblen System, was bedeutet, dass es in den meisten Fällen sogar auf einem Windows-Rechner funktionieren wird , zumindest wenn Sie die C-Laufzeitumgebung installiert haben . Im alten Unix begann ein Prozess sein Dasein nicht als isolierte kleine Schneekugel. Stattdessen wurde es mit drei bereits verbundenen offenen E/A-Kanälen ausgestattet : Standardeingabe, Standardausgabe und Standardfehlerausgabe. In C bezeichnen wir diese als Standardin, Standardout und Standardfehler. Die Namen spiegeln aber eigentlich die Sichtweise der C-Bibliothek auf die Welt wider. Darunter befinden sich in Unix die Dateideskriptoren, und das sind nichts anderes als kleine ganze Zahlen. Zum Beispiel ist die Standardeingabe der Deskriptor Null. Die Standardausgabe ist Deskriptor eins, der Standardfehler ist Deskriptor zwei. Das war’s. Null, eins und zwei. Die drei bekanntesten Ganzzahlen in Betriebssystemen. Und sie sind nicht magisch, weil sie das sind, was sie sind. Sie sind magisch, weil sie von jemandem inszeniert werden . Wenn Sie ein Programm über die Shell ausführen, erstellt die Shell die Umgebung, die das Programm erben wird. Wenn Sie einen Befehl normal eingeben, verweist der Deskriptor Null wahrscheinlich auf Ihre Tastatur oder Ihre Terminaleingabe. Der erste Deskriptor verweist auf Ihre Terminalausgabe. Auch der zweite Deskriptor verweist auf Ihre Terminalausgabe, ist aber konzeptionell davon getrennt. Und diese Trennung erweist sich als sehr wichtig . Wenn Sie ein Programm ausführen, das in output.text umgeleitet wird, sorgt die Shell dafür, dass der Deskriptor eins, die Standardausgabe , nicht mehr auf das Terminal verweist. Es verweist auf eine Datei. Das Programm hat normalerweise keine Ahnung, dass dies gerade passiert ist. Es schreibt einfach wie immer in seine Standardausgabe. Die Außenhülle hat die darunterliegende Rohrleitung ausgetauscht . Wenn Sie also ein Programm ausführen, das von input.text umgeleitet wurde, stammt der Deskriptor Null nun aus einer Datei anstatt von Ihrer Tastatur. Und wenn Sie das Programm so ausführen, dass der zweite Datenstrom in errors.text umgeleitet wird, wird der zweite Deskriptor, die Standardfehlerausgabe, in eine separate Datei geschrieben. Das Letzte ist keine nachträgliche historische Überlegung, die erst später hinzukam. Das ist einer der Gründe, warum Pipelines so gut funktionieren, wie sie es tun. Die Standardausgabe dient der Darstellung der nützlichen Daten, die Ihr Programm erzeugt. Der Standardfehler ist zum Meckern da. Wenn Ihr Programm eine Liste von Dateinamen generiert und Sie diese Liste an ein anderes Programm weiterleiten, möchten Sie nicht, dass zufällige Diagnosemeldungen wie Rosinen in einem ansonsten akzeptablen Keks in den Datenstrom gemischt werden. Und das ist der geniale Grund, warum es überhaupt einen Standardfehler gibt. Es ermöglicht Ihrem Programm zu sagen: „Hey, hier sind die Daten, die Sie angefordert haben.“ und sagen Sie separat: „Übrigens, da ist etwas Seltsames passiert.“ Der eine Strom besteht aus Fracht, der andere aus Funkverkehr . Hier kommt der Dateizeiger von C ins Spiel. Wenn Sie in einem Relay-Log mit r als Flags den Befehl file pointer f equals f open schreiben, erhalten Sie nicht die Datei zurück. Streng genommen ist es nicht einmal der eigentliche Handle des Betriebssystems. Unter Unix ist das primitive Datenelement üblicherweise der Dateideskriptor, diese kleine Ganzzahl. Die Funktion `open` gibt einen Zeiger auf ein C- Bibliotheksobjekt zurück, das als Datei bezeichnet wird. Und dieses Objekt leistet mehr Arbeit, als den meisten Menschen bewusst ist. Betrachten Sie den Dateideskriptor als eine Art Abholschein am Lagerschalter. Der Kernel weiß, was das Ticket bedeutet. Es erkennt, ob es sich um eine reale Datei, ein Terminal, eine Pipe oder ein Gerät handelt. Ein Dateizeiger hingegen ist, als würde man einen kleinen Angestellten einstellen, der das Ticket für einen verwaltet. Der Angestellte hat einen Puffer. Der Angestellte merkt sich, ob Sie lesen oder schreiben. Der Sachbearbeiter erkennt, ob Sie auf das Dateiende oder einen Fehler gestoßen sind. Der Sachbearbeiter bündelt Ihre Anfrage, damit sie nicht für jedes einzelne Byte im Kernel-Fenster ausgeführt werden muss. Und dieser Puffer ist entscheidend. Ohne Pufferung wäre der Aufruf von getc in einer Schleife katastrophal teuer, da für jedes Zeichen möglicherweise ein Systemaufruf erforderlich wäre . Ein Systemaufruf ist nicht einfach nur ein Funktionsaufruf. Es handelt sich um einen kontrollierten Übergang von Ihrem Programm in den Betriebssystemkern. Es bedeutet, die Erwachsenen im Sperrbereich zu bitten, in Ihrem Namen etwas Privilegiertes zu tun. Das ist zwar wirkungsvoll, aber nicht kostenlos. Standard-IO-Cheats werden also auf die bestmögliche Weise eingesetzt . Sie fragen nach einem Zeichen. Die C-Bibliothek liest im Hintergrund einen größeren Datenblock aus dem Kernel in einen Puffer ein. Dann können die nächsten hundert oder tausend Zeichen direkt aus dem Speicher abgerufen werden. Für Ihr Programm sieht es immer noch so aus, als würden Sie einen Datenstrom Byte für Byte oder Zeile für Zeile lesen . Im Hintergrund der Bibliothek findet die Stapelverarbeitung der Aufgaben statt. Das ist auch der Grund, warum printf manchmal wie von Geistern heimgesucht wirkt. Wenn der Standardausgang mit einem Terminal verbunden ist, wird er oft zeilenweise gepuffert, was bedeutet, dass die Ausgabe erst beim Drucken der neuen Zeile erscheint. Wenn die Standardausgabe in eine Datei oder eine Pipe umgeleitet wird, kann sie vollständig gepuffert sein, was bedeutet, dass sie wartet, bis der Puffer voll ist oder Sie ihn leeren. Der Standardfehler hingegen ist in der Regel ungepuffert oder wird zumindest viel dringlicher behandelt, da Fehlermeldungen auch dann erscheinen sollen, wenn etwas schiefgeht. Dies erklärt einen jener kleinen Fehler, denen jeder C-Programmierer irgendwann einmal in einer dunklen Gasse begegnet. Man gibt eine Eingabeaufforderung wie „Geben Sie Ihren Namen ein“ aus und ruft dann eine Funktion auf, die die Eingabe einliest. Und auf Ihrem Rechner funktioniert es einwandfrei. In manchen anderen Umgebungen wird die Eingabeaufforderung jedoch nicht angezeigt, weil keine neue Zeile vorhanden war, die Ausgabe zwischengespeichert wurde und niemand den Puffer geleert hat. Die Lösung ist nicht mystisch. Sie rufen einfach fflush auf dem Standardausgang auf. Das ist so, als würde man dem kleinen Angestellten sagen: „Hör auf, das festzuhalten. Liefer es sofort aus.“ Und sobald man versteht, dass der Dateizeiger ein gepuffertes Objekt ist, das auf einem tieferliegenden Betriebssystem-Handle sitzt, ergibt eine Menge seltsamer Verhaltensweisen plötzlich Sinn. Wenn Sie printf mit rohen Schreibaufrufen auf demselben Deskriptor mischen, können Sie zu überraschenden Ergebnissen kommen, da die C- Bibliothek und der Kernel nicht unbedingt übereinstimmen, welche Daten bereits physisch verschoben wurden. Wenn Sie einen Prozess verzweigen, nachdem Sie gepufferte Ausgaben gedruckt, aber bevor Sie den Puffer leeren, können sowohl der Eltern- als auch der Kindprozess denselben ausstehenden Puffer erben, und plötzlich wird eine Zeile, von der Sie dachten, sie sei einmal gedruckt worden, zweimal ausgegeben. Der Computer ist nicht verwirrt, Sie sind es. Und ich meine das im Sinne einer unterstützenden pädagogischen Tätigkeit . Nun lasst uns über die kleinen Modus-Strings sprechen, denn sie sehen aus wie kleine Zaubersprüche, und ehrlich gesagt sind sie das auch. R öffnet eine bestehende Datei zum Lesen. W öffnet eine Datei zum Schreiben, erstellt sie gegebenenfalls und kürzt sie, falls sie bereits existiert. Und „truncating“ ist ein Wortspiel für „alles, was einmal da war, ist jetzt vollständig verschwunden“, also hoffe ich, dass Sie das so gemeint haben. A öffnet sich zum Anhängen und erstellt die Datei gegebenenfalls zuerst. Dann gibt es noch die Varianten wie R+, W+ und A+, die sowohl das Lesen als auch das Schreiben ermöglichen, jede mit ihren eigenen Regeln. Unter Windows legen wir ebenfalls großen Wert auf den Binärmodus, daher sind RB und WB wichtig, da der Textmodus Zeilenumbrüche übersetzen kann. Unter Unix sind Binär- und Textmodus im Wesentlichen dasselbe, weil Unix sich die Übersetzung von Wagenrücklauf und Zeilenvorschub ansah und beschloss, dass es an diesem Nachmittag Besseres zu tun hatte. Besondere Beachtung verdient jedoch der Anfügemodus, denn er ist viel cooler, als er aussieht. Die meisten Programmierer denken, dass der Anfügemodus einfach bedeutet, dass die Dateiposition am Ende beginnt. Das wäre nützlich, aber nicht magisch. Der eigentliche Wert, zumindest auf POSIX-Systemen, liegt darin, dass der Anfügemodus normalerweise mit einem Kernel-Flag namens O_APPEND implementiert wird. Das bedeutet, dass jeder Schreibvorgang am Ende der Datei stattfindet, und zwar genau in dem Moment, in dem er ausgeführt wird, nicht beim Öffnen der Datei oder beim letzten Durchsuchen , sondern wenn der Kernel den Schreibvorgang durchführt. Und genau dieser Unterschied ist entscheidend. Stellen Sie sich zwei Programme vor, die beide in dieselbe Protokolldatei schreiben. Im Anfügemodus könnte jeder das Naheliegende tun, zum Ende springen und eine Zeile schreiben. Das Problem ist, dass beide dasselbe Ziel verfolgen können, bevor einer von ihnen schreibt. Dann schreibt der eine seine Zeile, der andere schreibt seine Zeile und geht entweder damit oder überschreibt sie, und jetzt sieht Ihre Protokolldatei so aus, als wäre sie von Waschbären zusammengebastelt worden. Der Anfügemodus verschiebt die Operation „Gehe zum Ende“ in den Schreibpfad des Kernels. Das bedeutet, dass der Schreibvorgang als Teil der Operation an das aktuelle Ende der Datei angehängt wird . Für Protokolldateien, Audit-Trails, Server- Traces und alles, wo mehrere Schreiber Datensätze hinzufügen könnten, ist dies nicht nur praktisch, sondern es ist der Unterschied zwischen einem Protokoll und einem Tatort. Es gibt einige Einschränkungen, denn es gibt immer einige Einschränkungen. Standardmäßige E/A- Pufferung kann immer noch das, was Sie als einen logischen Datensatz betrachten, in mehr als einen Schreibvorgang auf niedrigerer Ebene aufteilen. Netzwerkdateisysteme hatten historisch gesehen ihre ganz eigene Sammlung von Tücken. Und der Anfügemodus macht Ihr Anwendungsprotokoll nicht auf magische Weise atomar. Doch die Grundidee ist nach wie vor unglaublich wirkungsvoll. Wenn Sie etwas am Ende einer Datei hinzufügen möchten, bitten Sie den Kernel, diese Regel durchzusetzen, anstatt zu versuchen, sie im Benutzermodus zu simulieren. Nehmen wir an, Sie öffnen eine Datei mit A plus, springen zum Anfang zurück, lesen ein wenig und schreiben dann etwas. Die meisten Programmierer erwarten, dass der Schreibvorgang an der Stelle stattfindet, an der sie zuletzt versucht haben, zu schreiben. Im Anfügemodus wird der Schreibvorgang jedoch weiterhin bis zum Ende fortgesetzt. Die Position der Datei ist für das Lesen wichtig. Die Anfügeregel dominiert das Schreiben. Und genau dieses Verhalten erscheint einem seltsam, bis man erkennt, dass es dazu dient, eine Race Condition zu verhindern. Bisher haben wir über normale Dateien gesprochen, über schöne, gewöhnliche Dateien, Dateien mit Namen, Größen und Blöcken auf der Festplatte, also über die Art von Dateien, die Ihr Datei-Explorer versteht. Aber wenn wir hier aufhören, würden wir den besten Teil verpassen. Denn in Unix muss ein Pfadname nicht auf eine reguläre Datei auf der Festplatte verweisen. Öffne dev/null zum Schreiben, und jedes Byte, das du schreibst, verschwindet einfach. Es ist kein metaphorischer Mülleimer. Es handelt sich um das Gerät, das über den Dateisystem-Namensraum zugänglich gemacht wird . Ihr Programm kann dev/null mit Schreibzugriff öffnen und einen Dateizeiger erhalten und dann fröhlich fprintf in die Bedeutungslosigkeit ausgeben. Genauso können Sie dev/zero zum Lesen öffnen und erhalten einen endlosen Strom von Nullbytes, keine riesige Datei voller Nullen, sondern ein Gerät, das auf Abruf für immer Nullen erzeugt. Öffnen Sie dev/urandom, und Sie können zufällige Bytes aus dem Kernel lesen. Auch dies geschieht über eine dateiähnliche Schnittstelle. Öffnen Sie dev/tty, und Sie können mit dem steuernden Terminal kommunizieren, selbst wenn Standardeingabe und Standardausgabe umgeleitet wurden. Das ist ein ziemlich genialer Trick, um Pipe-Daten zu verarbeiten und dem Benutzer trotzdem eine Frage zu stellen. Da Ihr Eingabestrom möglicherweise aus einer Datei stammt, könnte Ihre Ausgabe an ein anderes Programm gehen, aber die Eingabe auf dev/tty bedeutet: "Nein, ich meine das eigentliche menschliche Terminal, das mit diesem Prozess verbunden ist." Man braucht es also nicht oft, aber wenn man es braucht, ist es unschätzbar wertvoll. Und dann gibt es noch proc, wo das Dateisystem sich anfühlt, als würde ein Zauberer Karten aus der Tasche ziehen. Auf vielen Unix-ähnlichen Systemen sind Dateien im Ordner proc keine gewöhnlichen Dateien auf der Festplatte. Es handelt sich um Einblicke in den Kernelzustand. Beim Lesen dieser Dateien synthetisiert der Kernel den Inhalt live. Sie können etwas öffnen, das wie eine Textdatei aussieht, und Informationen über die CPU, den Speicher, die Mounts oder die Prozesse lesen. Die Datei ist die Schnittstelle. Die Bytes werden erst erzeugt, wenn Sie sie anfordern. Als ich den Task-Manager für Windows schrieb, um Informationen über die laufenden Prozesse zu erhalten, rief man NT zweimal auf, um Systeminformationen abzufragen. Einmal, um herauszufinden, wie groß der benötigte Puffer sein muss, und dann ein zweites Mal, um eine Momentaufnahme der Prozessdaten zu liefern. Unter Unix öffnet man einfach eine Datei und liest sie. Es ist ein völlig anderer Ansatz, in mancher Hinsicht überlegen, in anderer unterlegen, aber wohl flexibler. Und das ist die Philosophie. Nicht jedes Programm sollte jeden Objekttyp verstehen können. Sorgen Sie dafür, dass die Objekte so sehr wie Dateien aussehen, dass bestehende Programme sie untersuchen, umleiten, filtern, protokollieren und zusammensetzen können. Und das führt uns zu einer der praktischsten Lektionen im C-API-Design. Schreiben Sie nach Möglichkeit Dateifunktionen, die einen Dateizeiger anstelle eines Dateinamens entgegennehmen. Eine Funktion, die nur einen Dateinamen entgegennimmt, kann nur eine Datei anhand ihres Namens sein. Eine Funktion, die einen Dateizeiger entgegennimmt, kann jedoch aus einer Datei, von der Standardeingabe, aus einer Pipe, von einem Gerät oder aus einem Datenstrom lesen, den jemand anderes bereits vorbereitet hat. Es ist wesentlich flexibler, weil es weniger anmaßend ist. Es verlangt nicht, dass die Sanitäranlagen im Besitz des Teams sind. Ein nettes kleines Beispiel ist eine Funktion namens CopyStream mit einer Eingabedatei und einer Ausgabedatei. Intern liest es einfach von einem Datenstrom und schreibt in den anderen. Sie können es verwenden, um eine Datei von einer Festplatte auf eine andere zu kopieren. Damit können Sie eine Standardeingabe in eine Standardausgabe kopieren. Man kann komprimierte Daten hindurchleiten. Du kannst es mit dev zero füttern. Sie können die Ausgabe an dev null senden. Es ist alles der gleiche Code, nur die Rohrleitungen sind anders. Es geht nicht nur um Bequemlichkeit, sondern auch um Verhandlungsmacht. Es gibt aber noch einige fortgeschrittenere Verwandte von F, die wahrscheinlich ihre eigenen Episoden verdienen, denn jede von ihnen öffnet eine neue Tür. Es gibt FD open, mit dem man einen vorhandenen Unix- Dateideskriptor in einen Dateizeiger einbetten kann. Das ist wichtig, denn nicht alles beginnt sein Dasein mit einem Dateinamen. Pipes, Sockets, doppelte Deskriptoren und geerbte Handles können bereits existieren. Wenn FD geöffnet ist, können Sie sagen: „Ich habe diese Low-Level-Sache. Bitte geben Sie mir die schöne, gepufferte Standard-E/A-Schnittstelle darüber zurück .“ Dann gibt es noch fileno, das in die andere Richtung geht. Anhand eines Dateizeigers können Sie den zugrunde liegenden Dateideskriptor abfragen , den Sie möglicherweise für Low-Level-Operationen wie select, poll, fsync, fcntl und ähnliches benötigen. Außerdem gibt es freopen, mit dem sich ein bestehender Datenstrom wie Standardausgabe oder Standardfehlerausgabe aus dem Programm heraus umleiten lässt. Und das ist nützlich für altmodische Protokollierung, Dämonenkonfiguration, Testumgebungen und Programme, die ihre eigene Ausgabe umschreiben möchten, ohne jedes printf zu ändern. Es gibt popen für Prozess öffnen, was Ihnen einen Dateizeiger liefert, der mit einem anderen Prozess verbunden ist. Sie können einen Befehl ausführen und dessen Ausgabe lesen, als wäre es eine Datei. Das ist gleichermaßen unglaublich nützlich und ein wenig gefährlich, was darauf hindeutet, dass es von Unix stammt. Und dann gibt es noch speicherbasierte Streams, benutzerdefinierte Streams, Socket-Wrap- Streams und allerlei clevere Mechanismen, die immer wieder denselben Punkt beweisen . Dateizeiger haben eigentlich nichts mit Festplattendateien zu tun. Es geht um Bäche. Aber wir müssen uns heute nicht mit all dem beschäftigen, denn die Kernidee ist bereits stark genug. Der Grund, warum fopen wichtig ist, liegt nicht darin, dass es Dateien öffnet. Viele Dinge öffnen Dateien. Die Bedeutung von fopen liegt darin, dass es an der Grenze zwischen einer sehr kleinen Programmierschnittstelle und einem sehr großen Betriebssystemkonzept steht. Sie bitten um einen Stream. Das Betriebssystem und die C- Laufzeitumgebung arbeiten zusammen, um Ihnen eines bereitzustellen. Vielleicht stammt der Datenstrom aus einem Flash- Speicher, vielleicht von einem Terminal, vielleicht von einer Pipe, vielleicht von einem Lochstreifenleser, vielleicht von einem Pseudogerät, vielleicht von einer vom Kernel erzeugten Illusion, die sich als Dateiname tarnt. Ihr Code kann Bytes lesen, Bytes schreiben, Puffer leeren, das Dateiende erkennen und Fehler behandeln – und das alles mit demselben kleinen Vokabular. Das ist kein Zufall. Das ist Design. Und es ist ein Designstil, den wir nach wie vor bewundern sollten. Moderne Software löst Probleme oft durch das Hinzufügen neuer Schichten, neuer Protokolle, neuer Objektmodelle, neuer Dienste, neuer Formate, neuer Abhängigkeiten usw., bis die eigentliche Sache unter einem Parkhaus der Architektur begraben ist. Unix hat hier etwas anders gemacht. Sie gestalteten die Benutzeroberfläche brutal einfach und passten die Welt ihr an . Nicht perfekt, nicht universell, nicht ohne einige seltsame Sonderfälle, aber gut genug, dass ein C-Programmierer auch ein halbes Jahrhundert später noch eine winzige Stream-Processing-Funktion schreiben und sie automatisch mit Dateien, Terminals, Pipes, Geräten und Dingen zum Laufen bringen kann, die sich der ursprüngliche Autor nie hätte vorstellen können. Und das ist die wahre Magie von F offen. Es ist keine große Veranstaltung, keine glamouröse Veranstaltung, sie hat kein Logo, keine Konferenz, keinen Zertifizierungsweg und keinen Cloud-Preisrechner. Es ist nur eine kleine Tür, aber auf der anderen Seite dieser Tür befindet sich eine der besten Ideen im Bereich der Informatik. Wenn man Dinge wie einen Bytestrom darstellen kann, kann man sie auch zusammensetzen. Und wenn man das einmal gesehen hat, dann wirkt das Öffnen von Daten mit R nie wieder so langweilig. Falls ihr die heutige Folge interessant oder unterhaltsam fandet, denkt daran, dass es mir dabei hauptsächlich um Abonnenten und Likes geht. Ich würde mich sehr geehrt fühlen, wenn Sie mir vor Ihrer Abreise heute noch je eines davon dalassen würden. Falls Sie Anmerkungen oder Fragen zu dieser Folge haben, hinterlassen Sie diese bitte unten in den Kommentaren. Und wenn Sie ein Fragezeichen verwenden, bedeutet das, dass Glenn es bemerken und herausziehen wird, und wir werden am Freitag in Shop Talk darüber sprechen , oder zumindest über die beste der Fragen. Wir versuchen, sie alle zu erreichen. Schaut euch die Folge unbedingt an, und wenn sie euch gefällt, abonniert den Kanal . Es ist auf dem Dave's Garage- Kanal zu finden, und ich werde hier einen Link einfügen. In der Zwischenzeit hoffen wir, Sie beim nächsten Mal wiederzusehen. Direkt hier in Daves Garage. Mach es , Glenn. Mach es. Mach es.


📊 Link-Infos

URL https://www.youtube.com/watch?v=XAzUoizwnXM
Titel fopen is Magic! – Find Out What You've Been Missing All These Years!
Kategorien BulkNews, Dave's Garage
Hinzugefügt 2026-07-18 00:21:37
Mediendatei Original-Medium ansehen · Lokale Kopie