Was macht das Öffnen einer Datei eigentlich?

266

In allen Programmiersprachen (die ich mindestens verwende) müssen Sie eine Datei öffnen, bevor Sie sie lesen oder schreiben können.

Aber was macht diese offene Operation eigentlich?

Handbuchseiten für typische Funktionen sagen Ihnen eigentlich nichts anderes als "öffnet eine Datei zum Lesen / Schreiben":

http://www.cplusplus.com/reference/cstdio/fopen/

https://docs.python.org/3/library/functions.html#open

Durch die Verwendung der Funktion können Sie natürlich feststellen, dass ein Objekt erstellt wird, das den Zugriff auf eine Datei erleichtert.

Eine andere Möglichkeit wäre, wenn ich eine openFunktion implementieren würde, was müsste sie unter Linux tun?

jramm
quelle
13
Bearbeiten dieser Frage, um sich auf CLinux zu konzentrieren; da unterscheidet sich was Linux und Windows machen. Ansonsten ist es etwas zu breit. Außerdem ruft jede übergeordnete Sprache entweder eine C-API für das System auf oder kompiliert sie zur Ausführung auf C herunter. Wenn Sie also auf der Ebene "C" bleiben, wird sie auf den kleinsten gemeinsamen Nenner gesetzt.
George Stocker
1
Ganz zu schweigen davon, dass nicht alle Programmiersprachen über diese Funktion verfügen oder dass diese stark von der Umgebung abhängt. Natürlich heutzutage selten, aber bis heute ist die Dateiverwaltung ein völlig optionaler Bestandteil von ANSI Forth und war in der Vergangenheit in einigen Implementierungen nicht einmal vorhanden.

Antworten:

184

In fast jeder Hochsprache ist die Funktion, die eine Datei öffnet, ein Wrapper um den entsprechenden Kernel-Systemaufruf. Es kann auch andere ausgefallene Dinge tun, aber in modernen Betriebssystemen muss das Öffnen einer Datei immer über den Kernel erfolgen.

Aus diesem Grund ähneln die Argumente der fopenBibliotheksfunktion oder Pythons openstark den Argumenten des open(2)Systemaufrufs.

Zusätzlich zum Öffnen der Datei richten diese Funktionen normalerweise einen Puffer ein, der folglich bei den Lese- / Schreibvorgängen verwendet wird. Mit diesem Puffer soll sichergestellt werden, dass der entsprechende Bibliotheksaufruf beim Lesen von N Bytes N Bytes zurückgibt, unabhängig davon, ob die Aufrufe der zugrunde liegenden Systemaufrufe weniger zurückgeben.

Ich bin eigentlich nicht daran interessiert, meine eigene Funktion zu implementieren. Nur um zu verstehen, was zum Teufel los ist ... "jenseits der Sprache", wenn Sie möchten.

In Unix-ähnlichen Betriebssystemen gibt ein erfolgreicher Aufruf zur openRückgabe eines "Dateideskriptors" zurück, der im Kontext des Benutzerprozesses lediglich eine Ganzzahl ist. Dieser Deskriptor wird folglich an jeden Aufruf übergeben, der mit der geöffneten Datei interagiert, und nach dem Aufrufen closewird der Deskriptor ungültig.

Es ist wichtig zu beachten, dass der Aufruf an openwie ein Validierungspunkt fungiert, an dem verschiedene Überprüfungen durchgeführt werden. Wenn nicht alle Bedingungen erfüllt sind, schlägt der Aufruf fehl, indem -1anstelle des Deskriptors zurückgegeben wird, und die Art des Fehlers wird in angezeigt errno. Die wesentlichen Überprüfungen sind:

  • Ob die Datei existiert;
  • Gibt an, ob der aufrufende Prozess berechtigt ist, diese Datei im angegebenen Modus zu öffnen. Dies wird bestimmt, indem die Dateiberechtigungen, die Eigentümer-ID und die Gruppen-ID mit den jeweiligen IDs des aufrufenden Prozesses abgeglichen werden.

Im Kontext des Kernels muss eine Art Zuordnung zwischen den Dateideskriptoren des Prozesses und den physisch geöffneten Dateien bestehen. Die interne Datenstruktur, die dem Deskriptor zugeordnet ist, kann einen weiteren Puffer enthalten, der sich mit blockbasierten Geräten befasst, oder einen internen Zeiger, der auf die aktuelle Lese- / Schreibposition zeigt.

Blagovest Buyukliev
quelle
2
Es ist erwähnenswert, dass in Unix-ähnlichen Betriebssystemen die Deskriptoren der Kernel-Strukturdatei "Open File Description" genannt werden. Prozess-FDs werden also Kernel-OFDs zugeordnet. Dies ist wichtig, um die Dokumentation zu verstehen. Zum Beispiel sehen man dup2und die Feinheit zwischen einem Scheck offenen Dateideskriptor (FD , die eine ist , das offen sein geschieht) und eine offene Dateibeschreibung (a OFD).
Rodrigo
1
Ja, Berechtigungen werden zur offenen Zeit überprüft. Sie können die Quelle für die "offene" Implementierung des Kernels lesen: lxr.free-electrons.com/source/fs/open.c, obwohl der größte Teil der Arbeit an den jeweiligen Dateisystemtreiber delegiert wird.
pjc50
1
(Auf ext2-Systemen müssen Sie die Verzeichniseinträge lesen, um festzustellen, in welchem ​​Inode sich die Metadaten befinden, und diesen Inode dann in den Inode-Cache laden. Beachten Sie, dass es möglicherweise Pseudofilesysteme wie "/ proc" und "/ sys" gibt, die beliebige Aktionen ausführen können wenn Sie eine Datei öffnen)
pjc50
1
Beachten Sie, dass die Überprüfung der geöffneten Datei - dass die Datei vorhanden ist, dass Sie die Berechtigung haben - in der Praxis nicht ausreicht. Die Datei kann unter Ihren Füßen verschwinden oder ihre Berechtigungen können sich ändern. Einige Dateisysteme versuchen dies zu verhindern, aber solange Ihr Betriebssystem Netzwerkspeicher unterstützt, kann dies nicht verhindert werden (ein Betriebssystem kann "in Panik geraten", wenn sich das lokale Dateisystem schlecht verhält und vernünftig ist: eines, das dies tut, wenn eine Netzwerkfreigabe dies nicht tut ein tragfähiges Betriebssystem). Diese Überprüfungen werden auch beim Öffnen der Datei durchgeführt, müssen jedoch (effektiv) auch bei allen anderen Dateizugriffen durchgeführt werden.
Yakk - Adam Nevraumont
2
Nicht zu vergessen die Auswertung und / oder Erstellung von Schlössern. Diese können gemeinsam genutzt oder exklusiv sein und sich auf die gesamte Datei oder nur auf einen Teil davon auswirken.
Thinkeye
83

Ich würde vorschlagen, dass Sie sich dieses Handbuch anhand einer vereinfachten Version des open()Systemaufrufs ansehen . Es wird das folgende Codefragment verwendet, das repräsentativ dafür ist, was beim Öffnen einer Datei hinter den Kulissen passiert.

0  int sys_open(const char *filename, int flags, int mode) {
1      char *tmp = getname(filename);
2      int fd = get_unused_fd();
3      struct file *f = filp_open(tmp, flags, mode);
4      fd_install(fd, f);
5      putname(tmp);
6      return fd;
7  }

Kurz gesagt, hier ist, was dieser Code Zeile für Zeile tut:

  1. Weisen Sie einen Block kernelgesteuerten Speichers zu und kopieren Sie den Dateinamen aus dem benutzergesteuerten Speicher hinein.
  2. Wählen Sie einen nicht verwendeten Dateideskriptor, den Sie sich als Ganzzahlindex vorstellen können, in eine erweiterbare Liste der aktuell geöffneten Dateien ein. Jeder Prozess hat eine eigene solche Liste, obwohl sie vom Kernel verwaltet wird. Ihr Code kann nicht direkt darauf zugreifen. Ein Eintrag in der Liste enthält alle Informationen, die das zugrunde liegende Dateisystem zum Abrufen von Bytes von der Festplatte verwendet, z. B. Inode-Nummer, Prozessberechtigungen, offene Flags usw.
  3. Die filp_openFunktion hat die Implementierung

    struct file *filp_open(const char *filename, int flags, int mode) {
            struct nameidata nd;
            open_namei(filename, flags, mode, &nd);
            return dentry_open(nd.dentry, nd.mnt, flags);
    }

    das macht zwei Dinge:

    1. Verwenden Sie das Dateisystem, um den Inode (oder allgemeiner die vom Dateisystem verwendete interne Kennung) nachzuschlagen, die dem Dateinamen oder Pfad entspricht, der übergeben wurde.
    2. Erstellen Sie eine struct filemit den wesentlichen Informationen zum Inode und geben Sie diese zurück. Diese Struktur wird zum Eintrag in der Liste der offenen Dateien, die ich zuvor erwähnt habe.
  4. Speichern ("installieren") Sie die zurückgegebene Struktur in der Liste der geöffneten Dateien des Prozesses.

  5. Geben Sie den zugewiesenen Block des kernelgesteuerten Speichers frei.
  6. Bringen Sie den Dateideskriptor, die dann zu Dateioperation Funktionen übergeben werden können , wie read(), write()und close(). Jeder von diesen übergibt die Steuerung an den Kernel, der den Dateideskriptor verwenden kann, um den entsprechenden Dateizeiger in der Prozessliste nachzuschlagen, und die Informationen in diesem Dateizeiger verwendet, um das Lesen, Schreiben oder Schließen tatsächlich durchzuführen.

Wenn Sie sich ehrgeizig fühlen, können Sie dieses vereinfachte Beispiel mit der Implementierung des open()Systemaufrufs im Linux-Kernel vergleichen, einer Funktion, die aufgerufen wird do_sys_open(). Sie sollten keine Probleme haben, die Ähnlichkeiten zu finden.


Dies ist natürlich nur die "oberste Ebene" dessen, was passiert, wenn Sie aufrufen open()- oder genauer gesagt, es ist der Kernelcode auf höchster Ebene, der beim Öffnen einer Datei aufgerufen wird. Eine Programmiersprache auf hoher Ebene kann darüber hinaus zusätzliche Ebenen hinzufügen. Auf niedrigeren Ebenen ist viel los. (Danke an Ruslan und pjc50 für die Erklärung.) Grob von oben nach unten:

  • open_namei()und dentry_open()invoke Dateisystem - Code, der auch Teil des Kernels ist, der Zugriff auf Metadaten und Inhalte für Dateien und Verzeichnisse. Das Dateisystem liest Rohbytes von der Festplatte und interpretiert diese Bytemuster als Baum von Dateien und Verzeichnissen.
  • Das Dateisystem verwendet die Blockgeräteschicht , die wiederum Teil des Kernels ist, um diese Rohbytes vom Laufwerk abzurufen. (Unterhaltsame Tatsache: Mit Linux können Sie mit /dev/sdaund dergleichen auf Rohdaten von der Blockgeräteebene zugreifen .)
  • Die Blockgeräteschicht ruft einen Speichergerätetreiber auf, der auch Kernelcode ist, um von einem Befehl mittlerer Ebene wie "Lesesektor X" in einzelne Eingabe- / Ausgabeanweisungen im Maschinencode zu übersetzen. Es gibt verschiedene Arten von Speichergerätetreibern, einschließlich IDE , (S) ATA , SCSI , Firewire usw., die den verschiedenen Kommunikationsstandards entsprechen, die ein Laufwerk verwenden kann. (Beachten Sie, dass die Benennung ein Chaos ist.)
  • Die E / A-Anweisungen verwenden die integrierten Funktionen des Prozessorchips und des Motherboard-Controllers, um elektrische Signale auf dem zum physischen Laufwerk führenden Kabel zu senden und zu empfangen. Dies ist Hardware, keine Software.
  • Am anderen Ende des Kabels interpretiert die Firmware der Festplatte (eingebetteter Steuercode) die elektrischen Signale, um die Platten zu drehen und die Köpfe (HDD) zu bewegen, oder liest eine Flash-ROM-Zelle (SSD) oder was auch immer für den Zugriff auf Daten erforderlich ist diese Art von Speichergerät.

Dies kann aufgrund von Caching auch etwas falsch sein . :-P Im Ernst, es gibt viele Details, die ich ausgelassen habe - eine Person (nicht ich) könnte mehrere Bücher schreiben, die beschreiben, wie dieser ganze Prozess funktioniert. Aber das sollte dir eine Idee geben.

David Z.
quelle
67

Jedes Dateisystem oder Betriebssystem, über das Sie sprechen möchten, ist für mich in Ordnung. Nett!


Bei einem ZX-Spektrum wird durch Initialisieren eines LOADBefehls das System in eine enge Schleife geraten und die Audio-In-Zeile gelesen.

Der Beginn der Daten wird durch einen konstanten Ton angezeigt. Danach folgt eine Folge von langen / kurzen Impulsen, wobei ein kurzer Impuls für eine Binärdatei 0und ein längerer für eine Binärdatei gilt 1( https://en.wikipedia.org/). wiki / ZX_Spectrum_software ). Die enge Ladeschleife sammelt Bits, bis sie ein Byte (8 Bits) füllt, dieses im Speicher speichert, den Speicherzeiger erhöht und dann zurückschleift, um nach weiteren Bits zu suchen.

In der Regel liest ein Loader als erstes einen kurzen Header mit festem Format , der mindestens die zu erwartende Anzahl von Bytes und möglicherweise zusätzliche Informationen wie Dateiname, Dateityp und Ladeadresse angibt. Nach dem Lesen dieses kurzen Headers kann das Programm entscheiden, ob der Hauptteil der Daten weiter geladen oder die Laderoutine beendet und eine entsprechende Meldung für den Benutzer angezeigt werden soll.

Ein Dateiende-Status kann erkannt werden, indem so viele Bytes wie erwartet empfangen werden (entweder eine feste Anzahl von Bytes, die in der Software fest verdrahtet sind, oder eine variable Anzahl, wie in einem Header angegeben). Ein Fehler wurde ausgelöst, wenn die Ladeschleife für eine bestimmte Zeit keinen Impuls im erwarteten Frequenzbereich empfangen hat.


Ein kleiner Hintergrund zu dieser Antwort

Das beschriebene Verfahren lädt Daten von einem normalen Audioband - daher muss Audio In gescannt werden (es ist mit einem Standardstecker an Tonbandgeräte angeschlossen). Ein LOADBefehl ist technisch identisch mit openeiner Datei, ist jedoch physisch an das tatsächliche Laden der Datei gebunden . Dies liegt daran, dass der Kassettenrekorder nicht vom Computer gesteuert wird und Sie eine Datei nicht (erfolgreich) öffnen, aber nicht laden können.

Die "enge Schleife" wird erwähnt, weil (1) die CPU, ein Z80-A (wenn Speicher dient), sehr langsam war: 3,5 MHz, und (2) das Spektrum keinen internen Takt hatte! Das bedeutet, dass die T-Zustände (Befehlszeiten) für jeden genau gezählt werden mussten. Single. Anweisung. innerhalb dieser Schleife, nur um das genaue Signalton-Timing aufrechtzuerhalten.
Glücklicherweise hatte diese niedrige CPU-Geschwindigkeit den entscheidenden Vorteil, dass Sie die Anzahl der Zyklen auf einem Blatt Papier und damit die reale Zeit berechnen konnten, die sie benötigen würden.

usr2564301
quelle
10
@ BillWoodger: Na ja. Aber es ist eine faire Frage (ich meine deine). Ich habe dafür gestimmt, als "zu breit" zu schließen, und meine Antwort soll veranschaulichen, wie extrem breit die Frage tatsächlich ist.
usr2564301
8
Ich denke, Sie erweitern die Antwort etwas zu sehr. ZX Spectrum hatte einen OPEN-Befehl, und das war völlig anders als bei LOAD. Und schwerer zu verstehen.
Rodrigo
3
Ich bin auch nicht einverstanden, die Frage zu schließen, aber ich mag Ihre Antwort wirklich.
Enzo Ferber
23
Obwohl ich meine Frage so bearbeitet habe, dass sie auf das Linux- / Windows-Betriebssystem beschränkt ist, um sie offen zu halten, ist diese Antwort vollständig gültig und nützlich. Wie in meiner Frage angegeben, möchte ich nicht etwas implementieren oder andere Leute dazu bringen, meine Arbeit zu erledigen, sondern lernen. Um zu lernen, müssen Sie die "großen" Fragen stellen. Wenn wir Fragen zu SO ständig schließen, weil sie zu weit gefasst sind, besteht die Gefahr, dass die Leute nur dazu gebracht werden, Ihren Code für Sie zu schreiben, ohne zu erklären, was, wo oder warum. Ich möchte es lieber als einen Ort behalten, an dem ich lernen kann.
Diagramm
14
Diese Antwort scheint zu beweisen, dass Ihre Interpretation der Frage zu weit gefasst ist und nicht, dass die Frage selbst zu weit gefasst ist.
JWG
17

Es hängt vom Betriebssystem ab, was genau passiert, wenn Sie eine Datei öffnen. Im Folgenden beschreibe ich, was unter Linux passiert, da es Ihnen eine Vorstellung davon gibt, was passiert, wenn Sie eine Datei öffnen und Sie den Quellcode überprüfen können, wenn Sie an weiteren Details interessiert sind. Ich gehe nicht auf Berechtigungen ein, da dies zu lange dauern würde.

Unter Linux wird jede Datei von einer Struktur namens inode erkannt. Jede Struktur hat eine eindeutige Nummer und jede Datei erhält nur eine Inode-Nummer. Diese Struktur speichert Metadaten für eine Datei, z. B. Dateigröße, Dateiberechtigungen, Zeitstempel und Zeiger auf Plattenblöcke, jedoch nicht den tatsächlichen Dateinamen selbst. Jede Datei (und jedes Verzeichnis) enthält einen Dateinameneintrag und die Inode-Nummer für die Suche. Wenn Sie eine Datei öffnen und davon ausgehen, dass Sie über die entsprechenden Berechtigungen verfügen, wird ein Dateideskriptor unter Verwendung der eindeutigen Inode-Nummer erstellt, die dem Dateinamen zugeordnet ist. Da viele Prozesse / Anwendungen auf dieselbe Datei verweisen können, verfügt inode über ein Verknüpfungsfeld, in dem die Gesamtzahl der Verknüpfungen zur Datei beibehalten wird. Wenn eine Datei in einem Verzeichnis vorhanden ist, beträgt ihre Linkanzahl eins. Wenn sie einen festen Link hat, beträgt ihre Linkanzahl zwei. Wenn eine Datei durch einen Prozess geöffnet wird, wird die Linkanzahl um 1 erhöht.

Alex
quelle
6
Was hat das mit der eigentlichen Frage zu tun?
Bill Woodger
1
Es beschreibt, was auf niedriger Ebene passiert, wenn Sie eine Datei unter Linux öffnen. Ich bin damit einverstanden, dass die Frage ziemlich weit gefasst ist, daher war dies möglicherweise nicht die Antwort, nach der jramm gesucht hat.
Alex
1
Also nochmal keine Überprüfung auf Berechtigungen?
Bill Woodger
11

Meistens Buchhaltung. Dies beinhaltet verschiedene Überprüfungen wie "Existiert die Datei?" und "Habe ich die Berechtigung, diese Datei zum Schreiben zu öffnen?".

Aber das ist alles Kernel-Zeug - es sei denn, Sie implementieren Ihr eigenes Spielzeug-Betriebssystem, es gibt nicht viel zu vertiefen (wenn Sie es sind, haben Sie Spaß - es ist eine großartige Lernerfahrung). Natürlich sollten Sie immer noch alle möglichen Fehlercodes kennen, die Sie beim Öffnen einer Datei erhalten können, damit Sie richtig damit umgehen können - aber das sind normalerweise nette kleine Abstraktionen.

Der wichtigste Teil auf Codeebene besteht darin, dass Sie ein Handle für die geöffnete Datei erhalten, das Sie für alle anderen Vorgänge verwenden, die Sie mit einer Datei ausführen. Könnten Sie nicht den Dateinamen anstelle dieses beliebigen Handles verwenden? Na klar - aber die Verwendung eines Griffs bietet Ihnen einige Vorteile:

  • Das System kann alle aktuell geöffneten Dateien verfolgen und verhindern, dass sie (zum Beispiel) gelöscht werden.
  • Moderne Betriebssysteme basieren auf Handles - es gibt unzählige nützliche Dinge, die Sie mit Handles tun können, und all die verschiedenen Arten von Handles verhalten sich fast identisch. Wenn beispielsweise ein asynchroner E / A-Vorgang für ein Windows-Dateihandle abgeschlossen wird, wird das Handle signalisiert. Auf diese Weise können Sie das Handle blockieren, bis es signalisiert wird, oder den Vorgang vollständig asynchron abschließen. Das Warten auf ein Dateihandle entspricht genau dem Warten auf ein Thread-Handle (signalisiert z. B. wenn der Thread endet), ein Prozesshandle (erneut signalisiert, wenn der Prozess endet) oder einen Socket (wenn ein asynchroner Vorgang abgeschlossen ist). Ebenso wichtig ist, dass Handles ihren jeweiligen Prozessen gehören. Wenn ein Prozess unerwartet beendet wird (oder die Anwendung schlecht geschrieben ist), weiß das Betriebssystem, welche Handles freigegeben werden können.
  • Die meisten Operationen sind positionell - Sie readvon der letzten Position in Ihrer Datei. Wenn Sie ein Handle verwenden, um eine bestimmte "Öffnung" einer Datei zu identifizieren, können Sie mehrere Handles gleichzeitig für dieselbe Datei verwenden, wobei jedes von seinem eigenen Ort aus gelesen wird. In gewisser Weise fungiert das Handle als bewegliches Fenster in die Datei (und als Möglichkeit, asynchrone E / A-Anforderungen auszugeben, die sehr praktisch sind).
  • Handles sind viel kleiner als Dateinamen. Ein Handle hat normalerweise die Größe eines Zeigers, normalerweise 4 oder 8 Bytes. Andererseits können Dateinamen Hunderte von Bytes haben.
  • Griffe ermöglichen das Betriebssystem zu bewegen , um die Datei, auch wenn Anwendungen haben es offen - der Griff nach wie vor gültig ist, und es zeigt immer noch auf die gleiche Datei, auch wenn der Name der Datei geändert hat.

Es gibt auch einige andere Tricks, die Sie ausführen können (z. B. das Teilen von Handles zwischen Prozessen, um einen Kommunikationskanal ohne Verwendung einer physischen Datei zu haben; auf Unix-Systemen werden Dateien auch für Geräte und verschiedene andere virtuelle Kanäle verwendet, sodass dies nicht unbedingt erforderlich ist ), aber sie sind nicht wirklich an die openOperation selbst gebunden , deshalb werde ich mich nicht damit befassen.

Luaan
quelle
7

Im Mittelpunkt der es beim Öffnen zum Lesen eigentlich nichts Besonderes muss passieren. Sie müssen lediglich überprüfen, ob die Datei vorhanden ist und die Anwendung über ausreichende Berechtigungen zum Lesen verfügt, und ein Handle erstellen, mit dem Sie Lesebefehle für die Datei ausgeben können.

Auf diesen Befehlen wird das eigentliche Lesen ausgelöst.

Das Betriebssystem hat häufig einen Vorsprung beim Lesen, indem es eine Leseoperation startet, um den dem Handle zugeordneten Puffer zu füllen. Wenn Sie dann tatsächlich lesen, kann der Inhalt des Puffers sofort zurückgegeben werden, anstatt auf der Festplatten-E / A warten zu müssen.

Zum Öffnen einer neuen Datei zum Schreiben muss das Betriebssystem einen Eintrag im Verzeichnis für die neue (derzeit leere) Datei hinzufügen. Und wieder wird ein Handle erstellt, auf dem Sie die Schreibbefehle ausgeben können.

Ratschenfreak
quelle
5

Grundsätzlich muss ein Aufruf zum Öffnen die Datei finden und dann aufzeichnen, was auch immer erforderlich ist, damit spätere E / A-Vorgänge sie wiederfinden können. Das ist ziemlich vage, aber es wird auf allen Betriebssystemen zutreffen, an die ich sofort denken kann. Die Besonderheiten variieren von Plattform zu Plattform. Viele Antworten hier sprechen bereits über moderne Desktop-Betriebssysteme. Ich habe ein wenig auf CP / M programmiert, daher werde ich mein Wissen darüber anbieten, wie es auf CP / M funktioniert (MS-DOS funktioniert wahrscheinlich genauso, aber aus Sicherheitsgründen wird es heute normalerweise nicht so gemacht ).

Auf CP / M haben Sie ein Ding namens FCB (wie Sie C erwähnt haben, können Sie es eine Struktur nennen; es ist wirklich ein zusammenhängender 35-Byte-Bereich im RAM, der verschiedene Felder enthält). Der FCB verfügt über Felder zum Schreiben des Dateinamens und einer (4-Bit-) Ganzzahl, die das Laufwerk identifiziert. Wenn Sie dann die Open File des Kernels aufrufen, übergeben Sie einen Zeiger auf diese Struktur, indem Sie ihn in eines der Register der CPU stellen. Einige Zeit später kehrt das Betriebssystem mit leicht geänderter Struktur zurück. Unabhängig davon, welche E / A Sie mit dieser Datei ausführen, übergeben Sie dem Systemaufruf einen Zeiger auf diese Struktur.

Was macht CP / M mit diesem FCB? Es reserviert bestimmte Felder für den eigenen Gebrauch und verwendet diese, um den Überblick über die Datei zu behalten. Sie sollten sie also niemals aus Ihrem Programm heraus berühren. Die Operation "Datei öffnen" durchsucht die Tabelle am Anfang der Festplatte nach einer Datei mit demselben Namen wie der FCB (das Platzhalterzeichen "?" Entspricht einem beliebigen Zeichen). Wenn eine Datei gefunden wird, werden einige Informationen in den FCB kopiert, einschließlich der physischen Speicherorte der Datei auf der Festplatte, sodass nachfolgende E / A-Aufrufe letztendlich das BIOS aufrufen, das diese Speicherorte möglicherweise an den Festplattentreiber weiterleitet. Auf dieser Ebene variieren die Besonderheiten.

OmarL
quelle
-7

In einfachen Worten, wenn Sie eine Datei öffnen, fordern Sie das Betriebssystem tatsächlich auf, die gewünschte Datei (Kopieren des Dateiinhalts) vom Sekundärspeicher in den RAM zur Verarbeitung zu laden. Der Grund dafür (Laden einer Datei) ist, dass Sie die Datei aufgrund ihrer im Vergleich zu Ram extrem langsamen Geschwindigkeit nicht direkt von der Festplatte verarbeiten können.

Der Befehl open generiert einen Systemaufruf, der wiederum den Inhalt der Datei vom Sekundärspeicher (Festplatte) in den Primärspeicher (Ram) kopiert.

Und wir 'schließen' eine Datei, weil der geänderte Inhalt der Datei in die Originaldatei auf der Festplatte übernommen werden muss. :) :)

Hoffentlich hilft das.


quelle