„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > GET NEXT LINE Ein Projekt, um zu lernen, wie man mit Dateideskriptoren und E/A des Systems umgeht

GET NEXT LINE Ein Projekt, um zu lernen, wie man mit Dateideskriptoren und E/A des Systems umgeht

Veröffentlicht am 07.11.2024
Durchsuche:174

Im Bereich der C-Programmierung ist die effektive Verwaltung von Eingabe, Ausgabe und Speicher von grundlegender Bedeutung. Um Ihnen das Verständnis dieser wichtigen Konzepte zu erleichtern, ist get_next_line ein Projekt, in dem Sie eine Funktion schreiben, die eine Datei Zeile für Zeile mithilfe eines Dateideskriptors liest. Bei jedem Aufruf der Funktion wird die nächste Zeile aus der Datei gelesen, sodass Sie den gesamten Dateiinhalt Zeile für Zeile verarbeiten können.

Dateideskriptoren und E/A in einem System verstehen

Was ist ein Dateideskriptor?

Ein Dateideskriptor ist eine nicht negative Ganzzahl, die eine geöffnete Datei in einem System eindeutig identifiziert. Wenn ein Programm eine Datei öffnet, gibt das Betriebssystem einen Dateideskriptor zurück, der verwendet werden kann, um bei nachfolgenden Vorgängen, z. B. beim Lesen, Schreiben oder Schließen der Datei, auf diese Datei zu verweisen. Dateideskriptoren sind eine Abstraktion, die vom Betriebssystem zur Verwaltung verschiedener E/A-Ressourcen verwendet wird, einschließlich Dateien, Sockets und Pipes.

0, 1 und 2 (Standardeingabe, Standardausgabe und Standardfehler) in Prozess A sind unabhängig und getrennt von den Dateideskriptoren in Prozess B. Durch diese Isolation wird sichergestellt, dass Dateioperationen in einem Prozess die Operationen in nicht beeinträchtigen ein anderer.

Dateideskriptortabelle

GET NEXT LINE A Project TO Learn How To Deal with File Descriptors and I/O of System

Jeder Dateideskriptor ist einem Eintrag in der Dateideskriptortabelle zugeordnet, der wesentliche Informationen über die Datei enthält. Dazu gehören der Dateipfad, Zugriffsberechtigungen und der aktuelle Offset, der die Position innerhalb der Datei für Lese-/Schreibvorgänge verfolgt. Diese Struktur ermöglicht es dem Betriebssystem, mehrere geöffnete Dateien effizient zu verwalten und den korrekten Zugriff und die Datenmanipulation sicherzustellen.

Beachten Sie, dass die Dateideskriptoren 0, 1 und 2 vom Betriebssystem für Standardstreams reserviert sind. Der Dateideskriptor 0 wird für die Standardeingabe (stdin) verwendet, die normalerweise Eingaben über die Tastatur darstellt. Dateideskriptor 1 wird für die Standardausgabe (stdout) verwendet, die die Ausgabe auf dem Bildschirm oder Terminal darstellt. Dateideskriptor 2 wird für den Standardfehler (stderr) verwendet, der auch die Ausgabe auf dem Bildschirm oder Terminal darstellt, aber speziell für Fehlermeldungen gedacht ist. Diese reservierten Dateideskriptoren stellen sicher, dass grundlegende Eingabe- und Ausgabevorgänge konsistent über verschiedene Programme und Umgebungen hinweg verwaltet werden können. Jeder von der open-Funktion zurückgegebene Dateideskriptor ist 3 oder höher, um sicherzustellen, dass er nicht mit diesen Standard-Streams in Konflikt steht.

wie man eine Datei öffnet

Beispiel

'#include '
'#include '

int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("Error opening file");
return 1;
}




Codeaufschlüsselung

Ein als Ganzzahl dargestellter Dateideskriptor wird mit der Funktion „open“ abgerufen, die zwei Parameter benötigt: den Dateinamen (oder Pfad) und Flags, die die Zugriffsberechtigungen der Datei bestimmen. Um beispielsweise den Inhalt einer Datei zu lesen, verwenden wir das Flag O_RDONLY (schreibgeschützt). Zum Lesen und Schreiben verwenden wir das Flag O_RDWR. Obwohl viele Flags verfügbar sind, verwenden wir für dieses Projekt nur O_RDONLY. Die Funktion „open“ gibt eine nicht negative Ganzzahl zurück, die bei erfolgreicher Operation der Dateideskriptor ist. Andernfalls wird -1 zurückgegeben, um auf einen Fehler hinzuweisen (Sie haben keine Berechtigung, auf example.txt zuzugreifen). Beachten Sie, dass sich die Öffnungsfunktion in der Bibliothek unistd.h befindet und die Berechtigungsflags in fcntl.h definiert sind.

Lesen aus einem Dateideskriptor

Beispiel

'#include '
'#include '
'#include '
'#define BUFFER_SIZE 4'

int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("Error opening file");
return 1;
}
char buffer[BUFFER_SIZE];
read(fd, buffer, sizeof(buffer)-1);
printf("1st call : %s\n", buffer);
// prints the first 3 bytes
read(fd, buffer, sizeof(buffer)-1);
printf("2nd call : %s\n", buffer);
read(fd, buffer, sizeof(buffer)-1);
printf("3rd call : %s\n", buffer);
read(fd, buffer, sizeof(buffer)-1);
printf("4th call : %s\n", buffer);
read(fd, buffer, sizeof(buffer)-1);
printf("5th call : %s\n", buffer);




abbauen

Codeergebnis

1. Aufruf: HEL
2. Aufruf: LO
3. Aufruf: WOR
4. Aufruf: LD
5. Aufruf: (null)

Die von der Bibliothek unistd.h bereitgestellte Lesefunktion wird zum Lesen von Daten aus einem Dateideskriptor verwendet. Es benötigt drei Parameter: den Dateideskriptor, einen Puffer zum Speichern der gelesenen Daten und die Anzahl der aus der Datei zu lesenden Bytes. Die Lesefunktion gibt die Anzahl der aus der Datei gelesenen Bytes zurück.

In der Dateideskriptortabelle gibt es ein Attribut namens Offset. Der Offset verfolgt die aktuelle Position innerhalb der Datei. Jedes Mal, wenn die Lesefunktion aufgerufen wird, liest sie Daten beginnend mit dem aktuellen Offset und erhöht dann den Offset um die Anzahl der gelesenen Bytes. Dadurch wird sichergestellt, dass nachfolgende Lesevorgänge dort fortgesetzt werden, wo der letzte Lesevorgang aufgehört hat.

GET NEXT LINE A Project TO Learn How To Deal with File Descriptors and I/O of System

In unserem Beispiel:

  • Der erste Aufruf von read liest die ersten 3 Bytes aus der Datei und speichert sie im Puffer, beginnend am Anfang der Datei (Offset 0). Der Offset wird dann auf 3 aktualisiert.
  • Der zweite Aufruf von read liest die nächsten 3 Bytes beginnend mit dem aktualisierten Offset (3) und aktualisiert dann den Offset auf 6.
    usw ...

  • Der fünfte Aufruf zum Lesen des Puffers ist null und der Lesevorgang gibt 0 zurück, was das Ende der Datei anzeigt.

Dieser Vorgang wird fortgesetzt, bis alle Daten aus der Datei gelesen wurden oder ein Fehler auftritt. Der Puffer wird nach jedem Lesevorgang nullterminiert, um sicherzustellen, dass er als Zeichenfolge gedruckt werden kann.

DAS PROBLEM

char *get_next_line(int fd) nimmt als Parameter einen Dateideskriptor einer Datei und gibt für jeden Aufruf eine Zeile zurück. Wenn das Ende der Datei erreicht ist, wird NULL zurückgegeben.

Parameter

  • fd: Dateideskriptor der Datei, aus der gelesen werden soll.
  • BUFFER_SIZE: Die Größe des Puffers, der zum Lesen von Blöcken aus der Datei verwendet wird. Ihr Programm sollte keine Lecks aufweisen.

Lösung :

https://github.com/Its-JoeTheKing/get_next_line

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/aerrfig/get-next-line-a-42-project-to-learn-how-to-deal-with-file-descriptors-and-io-of- system- 3652 Wenn ein Verstoß vorliegt, wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3