2010-12-27 6 views
6

In C wenn wir eine Datei öffnen, was passiert ?? Wie ich weiß, ist der Inhalt der Datei nicht in den Speicher geladen, wenn wir eine Datei öffnen. Es legt nur den Dateideskriptor fest? Also was ist dieser Dateideskriptor dann ?? Und wenn der Inhalt der Datei nicht im Speicher geladen ist, wie wird dann eine Datei geöffnet?Was ist das Öffnen einer Datei in C?

+2

-Datei benannt wird, welche Funktion verwenden Sie die Datei zu öffnen? – Thanatos

Antwort

2

C hat keine Primitiven für Datei-I/O, es hängt alles davon ab, welches Betriebssystem und welche Bibliotheken Sie verwenden.

+2

'fopen' ist das Primitive von C für Datei-E/A und ist nicht vom Betriebssystem abhängig. (Obwohl Sie häufig für bestimmte Funktionen OS-spezifische Funktionen aufrufen können.) – Thanatos

+1

Das ist nicht ganz korrekt. 'fopen' ist eine Bibliotheksfunktion, keine Primitive. Da der Dateizugriff immer vom Betriebssystem ausgeführt wird, ist 'fopen' tatsächlich vom Betriebssystem abhängig. Auf einem OS kann 'fopen' möglicherweise vorauslesen oder Puffer schreiben, auf einem anderen nicht. –

+0

nicht nur das, aber das Format der Zeichenfolge, auf die sich fopen bezieht, ist vollständig vom Betriebssystem abhängig. Drei populäre Wahlen benutzen/\ oder: als – ddyer

1

Dateideskriptoren sind nur Abstracts. Alles wird auf dem Betriebssystem ausgeführt.

0

Wie bereits erwähnt, ist es OS-Funktionalität.

Aber für C-Datei E/A höchstwahrscheinlich benötigen Sie Informationen über fopen Funktion.

Wenn Sie Beschreibung für diese Funktion überprüfen wird, heißt es:

Beschreibung:

einen Strom öffnet.

fopen öffnet die Datei mit dem Namen Dateiname und verbindet einen Stream mit es. fopen gibt einen Zeiger zurück, der verwendet werden soll , um den Datenstrom in nachfolgenden -Operationen zu identifizieren.

Also bei erfolgreicher Beendigung fopen gibt nur einen Zeiger auf den neu geöffneten Stream zurück. Und es gibt NULL zurück, wenn irgendein Fehler auftritt.

6

Normalerweise, wenn Sie eine Datei mit fopen oder (auf einem POSIX-System) open, die Funktion, wenn sie erfolgreich öffnen, wird „öffnen Sie die Datei“ - es gibt lediglich einen Wert (ein FILE * oder int) um in Zukunft Aufrufe einer Lesefunktion zu verwenden.

Unter der Haube, könnte das Betriebssystem lesen einige oder alle der Datei in, es könnte nicht. Sie müssen eine Funktion aufrufen, um zu verlangen, dass Daten sowieso gelesen werden, und wenn sie es nicht bis zum Zeitpunkt fread/fgets/read/etc ... getan hat, dann wird es an diesem Punkt.

Ein "Dateideskriptor" bezieht sich normalerweise auf die Ganzzahl, die von open in POSIX-Systemen zurückgegeben wird. Es wird verwendet, um eine geöffnete Datei zu identifizieren. Wenn Sie irgendwo einen Wert 3 bekommen, verfolgt das Betriebssystem, dass 3 sich auf /home/user/dir/file.txt oder was auch immer bezieht. Es ist ein kurzer kleiner Wert, um dem OS anzuzeigen, welche Datei zu lesen ist. Wenn Sie open anrufen, und öffnen Sie sagen, foo.txt, sagt das Betriebssystem, "ok, Datei öffnen, rufen Sie es von hier auf 3".

1

Wenn das Programm verwendet fopen() dann ein Pufferpaket eine Implementierung spezifische Systemaufruf verwenden, um einen Dateideskriptor zu erhalten, und es wird es in einer FILE Struktur zu speichern.

Der Systemaufruf (zumindest unter Unix, Linux und Mac) wird sich auf (normalerweise) ein festplattenbasiertes Dateisystem umsehen, um die Datei zu finden. Es erstellt Datenstrukturen im Kernel-Speicher, die die Informationen zum Lesen oder Schreiben der Datei sammeln.

Es erstellt auch eine Tabelle für jeden Prozess, der mit den anderen Kernel-Datenstrukturen verknüpft, die für den Zugriff auf die Datei erforderlich sind. Der Index in diese Tabelle ist eine (normalerweise) kleine Zahl. Dies ist der Dateideskriptor, der vom Systemaufruf an den Benutzerprozess zurückgegeben und dann in der FILE-Struktur gespeichert wird.

4

Diese Frage bezieht sich nicht ausschließlich auf die Programmiersprache. Obwohl die Bibliothek einen Einfluss darauf hat, was beim Öffnen einer Datei geschieht (z. B. open oder), stammt das Hauptverhalten vom Betriebssystem.

Linux, und ich nehme an, dass andere Betriebssysteme in den meisten Fällen Vorauslesen durchführen. Dies bedeutet, dass die Datei tatsächlich aus dem physischen Speicher gelesen wird, bevor Sie die Datei read aufrufen. Dies wird als eine Optimierung durchgeführt, die die Zeit für das Lesen verringert, wenn die Datei tatsächlich vom Benutzer gelesen wird. Dieses Verhalten kann teilweise durch den Programmierer unter Verwendung eines spezifischen Merkers für die offenen Funktionen gesteuert werden. Zum Beispiel kann die Win32-API CreateFileFILE_FLAG_RANDOM_ACCESS oder FILE_FLAG_SEQUENTIAL_SCAN angeben, um einen wahlfreien Zugriff (in diesem Fall wird die Datei nicht vorauslesen) oder sequentiellen Zugriff (in diesem Fall wird das Betriebssystem ziemlich aggressive lesen voraus) zu spezifizieren. Andere OS-APIs geben möglicherweise mehr oder weniger Kontrolle.

Für die Grund ANSI C API von open, read, write die einen Dateideskriptor verwenden, ist der Dateideskriptor eine einfache ganze Zahl, die auf dem Betriebssystem übergeben wird, und bedeutet die Datei. Im Betriebssystem selbst wird dies meistens in eine Struktur übersetzt, die alle benötigten Informationen für die Datei enthält (Name, Pfad, Suchoffsets, Größe, Lese- und Schreibpuffer usw.). Das Betriebssystem öffnet die Datei - das heißt, den spezifischen Dateisystemeintrag (inode unter Linux) zu finden, der mit dem Pfad in der open-Methode übereinstimmt, die Dateistruktur erstellt und dem Benutzer eine ID zurückgibt - den Dateideskriptor. Ab diesem Zeitpunkt kann das Betriebssystem alle Daten lesen, die es für richtig hält, selbst wenn es nicht vom Benutzer angefordert wird (es wird oft mehr gelesen, als angefordert wurde, um zumindest in der nativen Dateigröße zu arbeiten).

0

Wenn Sie die Datei öffnen dann die Dateizeiger die Adresse Basis bekommt (Startadresse) dieser file.Then Sie verschiedene Funktionen nutzen, auf die Datei zu arbeiten. EDIT: Dank Chris, hier ist die Struktur, die

typedef struct { 
     int    level;  /* fill/empty level of buffer */ 
     unsigned  flags;  /* File status flags   */ 
     char   fd;   /* File descriptor   */ 
     unsigned char hold;  /* Ungetc char if no buffer */ 
     int    bsize;  /* Buffer size    */ 
     unsigned char *buffer; /* Data transfer buffer  */ 
     unsigned char *curp;  /* Current active pointer  */ 
     unsigned  istemp;  /* Temporary file indicator */ 
     short   token;  /* Used for validity checking */ 
}  FILE; 
+0

nicht genau. Der "Dateizeiger" auf einen Datenstrom (der eine literale Datei oder etwas anderes sein kann) ist eigentlich kein Zeiger auf die Daten der Datei, sondern ein Zeiger auf eine Struktur, die Zugriffsinformationen einschließlich des zugrunde liegenden Dateideskriptors und des Lesevorgangs speichert Zeiger. Der Lesezeiger würde normalerweise am Anfang der Datei initialisiert werden. Die Funktion fopen() gibt jedoch einen Zeiger auf die Struktur zurück, nicht auf die Daten in der Datei. Um einen tatsächlichen dereferenzierbaren Zeiger auf die Daten der Datei zu erhalten, verwenden Sie open(), um einen Dateideskriptor (und nicht fopen()) und dann mmap() zu erhalten. –

+0

Dateistrukturen sind vom Betriebssystem abhängig. Einige Strukturen können den logischen Sektor und die Plattennummer des Anfangs der Datei enthalten. Andere können Berechtigungen und den Dateinamen enthalten. –

Verwandte Themen