6. Datei-Eingabe und -Ausgabe

Ähnliche Dokumente
8. Datei-Eingabe und -Ausgabe

8. Datei-Eingabe und -Ausgabe

6. Eingabe und Ausgabe, Dateien

2. Programmierung in C

Ein-/Ausgabe, Dateisystem. Kapitel 9: Ein-/Ausgabe. Programmieren in C für Elektrotechniker. Programmieren in C. Dateisystem. Programmieren in C

Dateioperationen Fachhochschule Würzburg-Schweinfurt Prof. Dr. Martin Ochs. Abspeichern und Einlesen von Texten (Strings) in Dateien

Dateizugriff unter C

Programmiersprachen Einführung in C

Dateien (1) Datenströme

high level I/O/ low level I/O

Physische Dateistrukturen

8. Arbeiten mit Dateien

182. stdio stdio. Eingabe. Ausgabe. Typisch für Zeileneingabe und Analyse: #include <stdio.h>

Im Windows Betriebssystem sind Dateien eindeutig gekennzeichnet durch ihren Pfad, Dateinamen und nach einem Punkt die Dateierweiterung.

Dateien. INE2, Mittwoch / TE402 M. Thaler, Office TG208. ZHAW, M. Thaler, K. Rege, G.

Informatik für Ingenieure (InfIng)

Tafelübung zu BS 4. Dateioperationen

Dateien. INE2 M. Thaler, Office TG208. ZHAW, M. Thaler, K. Rege, G. Burkert

Beispiel / Übung: Prof. Dr. A. Christidis WS 2012/13

file:///h:/dokumente/_fh/ ws /etinfoii/vorlesung/infoii...

E-/A-Funktionalität nicht Teil der Programmiersprache

FILE *fp; char fname[100];... fp = fopen (fname, rb ); if( fp == NULL ) { perror( fopen );... } // Fehlernachricht auf letzten Fehler, der aufkam

Modellierung und Programmierung

Ausgewählte Bibliotheksfunktionen

Programmieren in C. Die C-Standardbibliothek: Datei Ein- und Ausgabe. Prof. Dr. Nikolaus Wulff

Algorithmen & Programmierung. Persistenz - Arbeit mit Dateien

PROGRAMMIEREN MIT UNIX/LINUX-SYSTEMAUFRUFEN

Einführung in die Programmierung für Physiker. Die Programmiersprache C Ein- und Ausgabe

Michael Dienert. 8. Dezember 2016

Programmiertechnik 1. Unit 12: Programmiersprache C - Betriebssystemschnittstellen. Andreas Polze 1

Tafelübung zu BS 5. Dateioperationen

I/O-Hardware Grundlagen. Ein- und Ausgabe. Memory-Mapped I/O. Device Controller

File I/O. Persistieren von Daten. Gastvorlesung Ralph Erdt erdt (bei) informatik.fh-wiesbaden.de

Übersicht. Informatik 1 Teil 10 Dateien

Input, Output, Dateien

Einführung in die Programmiersprache C

Dateien lesen und schreiben mit php

5. Dateioperationen. Tafelübung zu BSRvS1. Olaf Spinczyk Arbeitsgruppe Eingebettete Systemsoftware. Lehrstuhl für Informatik 12 TU Dortmund

Programmierung mit C Datei-Ein- und Ausgabe

Betriebssysteme. Tafelübung 5. Dateioperationen. Daniel Friesel.

INE1 Ein-/Ausgabe, Dateien (Files) Einführung Datenstruktur und Operationen Textdateien Binärdateien Standard Streams

und noch ein Spiel Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Rechner muß unterschiedliche Geräte bedienen können. zeichenorientierte Geräte (character devices, unstructured devices)

GI Vektoren

Programmieren in C++

Die elementare Ausgabe von Daten auf externe Medien, wie Dateien und das Einlesen davon wird demonstriert.

Programmieren 1 C Überblick

Übungen zur Systemprogrammierung 1 Michael Golm, Jürgen Kleinöder Universität Erlangen-Nürnberg Informatik 4,

Dr. Monika Meiler. Inhalt

6.2 Extras/Lesen aus Dateien

Strukturen können wie normale Variablen an Funktionen übergeben werden. Strukturen können auch Ergebnis einer Funktion sein

Einteilung von Dateien. Streams

Programmierkurs Kapitel 4: Dateien Seite 1. Verwaltungfeld im Speicher. 4.1 Alternativen zur Programmierung der Eingabe und der Ausgabe

Was machen wir heute? Betriebssysteme Tutorium 10. Frage 10.1.a. Frage 10.1.a

Datei-Verarbeitung. Peter Sobe 60

I Dateisysteme. I.1 Allgemeine Konzepte. Einordnung. Prozessor (CPU, Central processing unit) Ein-, Ausgabegeräte/ Periphere Geräte (I/O Devices)

Permanente Datenspeicherung. Permanente Datenspeicherung. Agenda für heute, 1. Juni, 2006

Ein- und Ausgabe. C - Kurs Mario Bodemann. 15. September 2010

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 23

Programmiersprachen Einführung in C

Übungen zu Systemnahe Programmierung in C (SPiC) Sommersemester 2018

Einführung in die Programmierung für Physiker. Die Programmiersprache C Ein- und Ausgabe

Teil 7: Präprozessor und Ein-/Ausgabe Gliederung

Eine Mini-Shell als Literate Program

Inhalt Streams Eingabe / Ausgbe in C Dateizugriff in C Eingabe / Ausgabe in C++ Dateizugriff in C++ Error Handling

E.1 Allgemeine Konzepte (3) E.1 Allgemeine Konzepte (2) E.1 Allgemeine Konzepte. Datei. Einordnung. Katalog / Verzeichnis

Konzepte von Betriebssystem-Komponenten. I/O: von der Platte zur Anwendung

Ein- und Ausgabe. C - Kurs Mario Bodemann. 15. September 2010

U5 Verzeichnisse und Sortieren

Ein- und Ausgabe mit Dateien

Tafelübung zu BS 5. Dateioperationen

Tafelübung zu BS 5. Dateioperationen

MatLab Teil 2: weitere Operationen, Dateien und Bildformate

Das C Seminar Walter Herglotz WJH-BOD 1

4.3 Directories / Filesysteme

Übersicht. C Ein-/Ausgabe und Kontrollanweisungen. I/O-Funktionen aus stdio. printf() Ein-/Ausgabe. Kontrollanweisungen.

Dienstspezifikation nach RFC

Einführung in C. Alexander Batoulis. 5. Mai Fakutltät IV Technische Universität Berlin

Einführung in die C-Programmierung

Zeiger in C und C++ Zeiger in Java und C/C++

1. Allgemeine Datei (Binärdatei mit formatierten Inhalt)

Zeichendarstellung. Zeichen sind Zahlen (in C) Zeichen und switch

Ein- und Ausgabe mit Dateien

Softwareentwicklung I

Übungen zu Systemnahe Programmierung in C (SPiC)

Programmierung mit C Zeiger

Linux/Unix Systemprogrammierung

Inhalt. Übungen zu Systemnahe Programmierung in C (SPiC) Dateikanäle. Inhalt. Dateien & Dateikanäle Dateikanäle Ein-/Ausgaben

6 Ein- und Ausgabe. Bisher war unsere (Bildschirm-) Ausgabe leichtflüchtig (

MMC/SD FAT 16 mit AVR und C

RO-Tutorien 15 und 16

Dateiverarbeitung Pearson Education, Inc. All rights reserved.

Übersicht Shell-Scripten

Transkript:

Dateien: 6. Datei-Eingabe und -Ausgabe sind benannte Objekte, die eine Speicherung von Anwendungsdaten auf einem linearen Adressraum zulassen Persistente Speicherung, d.h. Daten bleiben nach Beendigung der Anwendung und auch nach Abschalten des Systems erhalten Dateisystem als Teil des Betriebssystems sorgt für Zugriff mit Dateinamen, Verzeichnisse, Pufferung, Zugriffsschutz Datei-Daten können beliebig strukturiert sein: Binärdaten Textdaten (lesbarer Text) XML-Datenformate Hinweis auf Typ/Struktur der Datei über Dateityp, z.b. bei bild.jpg wird eine Bilddatei im JPEG-Format angenommen Der Zugriff auf Daten in Dateien findet unter vollständiger Kontrolle des Anwendungsprogramms statt Peter Sobe 1 Datei-Eingabe und -Ausgabe Anwendungsprogramm Anwendung liest, verarbeitet und speichert Daten Bibliotheken und Funktionen der Ausführungsplattform Betriebssystem Dateisystem Platten-Controller Pufferung, Zusatzfunktionen wie z.b. Dialoge zum Auswählen einer Datei Betriebssystem stellt einheitliche Schnittstelle zu Dateisystemen bereit Dateisystem realisiert lineare Blockadressierung, Verzeichnisse, Zugriffsrechte u. mehr Daten werden durch Dateisystem auf ein block-orientiertes Gerät abgebildet Gerätetreiber und Plattencontroller sprechen Platten und dort jeweils Blöcke (Zylinder, Sektor, Kopf) an. Peter Sobe 2

Datei-Eingabe und -Ausgabe In C sind eine Reihe von Standarddateien vordefiniert: ZEIGER stdin stdout stderr GERÄTEDATEI Standardeingabe Standardausgabe Standardfehlerausgabe Diese Standard-Datei-Zeiger sind in jedem C-Programm definiert und die zugehörigen Gerätedateien werden bei Start geöffnet. Peter Sobe 3 Zugriffsarten zu Dateien In C existieren zwei Zugriffsarten: High-Level-Zugriff: über Standardbibliothek, gepuffert Low-Level-Zugriff: direkte Funktionen der Betriebssystemschnittstelle, im Anwendungsprozess nicht gepuffert Für jede Zugriffsart steht jeweils eine Menge bestimmter E/A-Funktionen zur Verfügung. Bei beiden Zugriffsarten stellt die Datenverwaltung des Betriebssystems den Inhalt der Datei unabhängig von der Dateiorganisationsform als Strom von Zeichen dar. Zuerst wird der High-Level-Zugriff erklärt, später folgt der Low-Level-Zugriff (ab Folie 28) Peter Sobe 4

Zugriffsprinzipien In C existieren folgende Zugriffsprinzipien: zeichenweise E/A (sequentiell) zeilenweise E/A (sequentiell) formatierte E/A (sequentiell) direkte E/A (über direkte Positionierung, nicht sequentiell) Für jedes Zugriffsprinzip steht jeweils eine Menge bestimmter Ein- und Ausgabefunktionen zur Verfügung. Beim formatierten Zugriffsprinzip kann über die Formatsteuerung im Strom von Zeichen andere Objekte, wie Zahlen usw. identifiziert und verarbeitet werden. Peter Sobe 5 Typische Abfolge der Funktionsaufrufe 1. Datei öffnen Nach Angabe eines Dateinamens und des Zugriffsmodus wird eine Datei geöffnet. Nachfolgende Funktionen können ein Datei-Handle (FILE *f) als Referenz auf die geöffnete Datei benutzen. Es können mehrere Dateien gleichzeitig geöffnet werden. 2. (wahlweise Positionieren), Zugriffe: Zugriffe erfolgen standardmäßig von Anfang des Dateiinhalts. Ein s.g. Dateipositionszeiger wird mit jedem Zugriff weitergestellt und aufeinander folgende Zugriffe beziehen sich damit auf fortlaufende Dateiinhalte (sequentielle Organisation, vgl. Abspielen von Musik von CD). Es gibt Funktionen zum expliziten Positionieren. 3. Datei schließen: Soll kein weiterer Zugriff auf die Datei mehr erfolgen, wird die Datei (über die Angabe des Datei-Handle) geschlossen. Damit werden Inhalte und Änderungen für andere Anwendungsprozesse sichtbar. Peter Sobe 6

Zugriff auf Text- vs. Binärdateien Textdateien, mit lesbarem Text (z.b. im Editor) Funktionen für zeichenweise Ein- und Ausgabe (E/A): fgetc(), fputc() wird z.b. als file get character gelesen zeilenweise E/A: fgets(), fputs() formatierte E/A: fscanf(), fprintf() Binärdateien, deren Inhalt die interne Repräsentation der Daten enthält, nicht (ohne weiteres) mit einem Editor lesbar blockweise und elementweise E/A: fread(), fwrite() Peter Sobe 7 Zugriffsmodi beim Öffnen einer Datei In C bestimmen die Zugriffsmodi, wie eine Datei prinzipiell zu verarbeiten ist. Die Modi werden bei der Öffnung der Datei als Zeichenfolge angegeben: Zugriffsmodus Ziel r w eine bestehende Datei wird zum Lesen geöffnet. fopen() liefert einen NULL-Zeiger, wenn Datei nicht existiert oder nicht gefunden wird (Pfad!) Datei zum Schreiben öffnen. Die Datei wird erzeugt, wenn sie noch nicht existiert. Existiert die Datei, wird der alte Inhalt überschrieben. Peter Sobe 8

Zugriffsmodi (Fortsetzung) Zugriffsmodus Ziel a r+ w+ Datei zum Anfügen öffnen, d.h. es wird am Dateiende weiter geschrieben. Die Datei wird erzeugt, wenn sie noch nicht existiert. Bestehende Datei zum Lesen und Schreiben öffnen. fopen() liefert den NULL-Zeiger zurück, wenn sie nicht existiert. Bestehende Datei zum Schreiben und Lesen öffnen. Existiert die Datei, wird ihr Inhalt überschrieben. Peter Sobe 9 Zugriffsmodus Zugriffsmodi (Fortsetzung) Ziel a+ Die Datei wird zum Lesen und Anfügen geöffnet. Die Datei wird erzeugt, wenn sie nicht existiert. Zusatzangabe zur Unterscheidung von Dateiarten: t b Datei wird als Text- (ASCII-) Datei betrachtet. t ist Standard und kann weggelassen werden. Datei wird als Binär- Datei betrachtet. Die Zusatzangabe wird dem Zugriffsmodus hinzugefügt, z.b. rt, wb, at+, rb+ usw. Peter Sobe 10

Text- und Binär-Dateien Fehlt die Zusatzangabe zur Unterscheidung von Dateiarten so wird standardmäßig t für Text- (ASCII-) Datei angenommen. Der Unterschied zwischen Text- und Binärdateien besteht in der Behandlung des Zeilenendes. Wird eine Datei als Textdatei geöffnet, wird das Zeilenende nur durch das Zeichen Linefeed \n ASCII-Wert 10 dargestellt. Wird eine Datei als Binärdatei geöffnet, wird das Zeilenende durch zwei Zeichen CariageReturn+Linefeed \r\n ASCII- Wert 13+10 dargestellt. Damit hat die Datei eine unterschiedliche Länge! Peter Sobe 11 High-Level-Zugriff zu Dateien FILE-Struktur Zeiger auf Puffer Zeiger auf nächstes Zeichen im Puffer Anzahl Zeichen im Puffer Deskriptor Daten schreiben Daten schreiben Datei-Handle Programm Daten lesen Puffer Daten lesen Datei Peter Sobe 12

High-Level-Zugriff: Öffnen und Schließen In C wird eine Datei mit fopen bzw. fclose geöffnet bzw. wieder geschlossen. Dabei muss das Datei-Handle (FILE *) deklariert sein: #include <stdio.h> void main() { FILE *fp; //Deklaration Datei-Handle fp = fopen( c:\\meinefreunde.txt, r );... fclose(fp); //Pfad-Angabe Kann die Datei nicht geöffnet werden, ist fp mit NULL belegt. Deshalb sollte nach fopen das Dateihandle auf NULL getestet werden, ehe eine Verarbeitung eingeleitet wird. Peter Sobe 13 Öffnen und Schließen einer Datei Die Funktion fopen erfordert für Datei- und Ordnernamen die Einhaltung der Konventionen für Dateinamen Die Funktion fclose erzeugt bei erfolgreichem Schließen der Datei den Rückkehrwert 0, sonst einen Fehlercode. Peter Sobe 14

High-Level-Zugriff: Zeichenweises Lesen In C wird mit fgetc eine Datei zeichenweise gelesen: #include <stdio.h> void main() { char c; FILE *fp; fp = fopen( c:\\dat.txt, r ); if (fp!=null) { c=fgetc(fp); //Lesen nächstes Zeichen if (c==eof)... //Prüfen auf EndOfFile fclose(fp); Nach jeder Leseoperation sollte auf das Erreichen des Dateiendes (EOF) getestet werden. Peter Sobe 15 High-Level-Zugriff: Zeichenweises Lesen Typischerweise kann man in C-Programmen beim zeichenweisen Lesen und Verarbeiten einer Datei eine nichtabweisende Schleife verwenden: #include <stdio.h> void main() { char c; FILE *fp; fp = fopen( c:\\dat.txt, r ); if (fp!=null) { do { c=fgetc(fp); //Lesen nächstes Zeichen... Verarbeitungsanweisungen while (c!=eof) ; //Prüfen auf End Of File if (! fclose(fp)) // ungleich 0 -> Erfolg printf( Datei erfolgreich geschlossen ); Peter Sobe 16

High-Level-Zugriff: Zeichenweises Schreiben In C wird mit fputc eine Datei zeichenweise geschrieben: #include <stdio.h> void main() { char c; FILE *fp; fp = fopen( c:\\dat.txt, w ); c= A ; fputc(c,fp); //Schreiben Zeichen c... fclose(fp); Peter Sobe 17 High-Level-Zugriff: Zeilenweises Lesen In C wird mit fgets eine Datei zeilenweise gelesen. Dabei muss im Programm ein Pufferspeicher als char-feld vereinbart werden, der die eingelesene Zeile aufnimmt. Es ist zweckmäßig, einen char-zeiger zu deklarieren, der durch fgets belegt wird und auf den Anfang des Puffers zeigt bzw. auf NULL im Fehlerfall oder bei Erreichen des Dateiendes. char puffer[81]; char *z; FILE *fp; z=fgets(puffer,81,fp); //Lesen Zeile Peter Sobe 18

High-Level-Zugriff: Zeilenweises Lesen Die Funktion fgets arbeitet dabei folgendermaßen: z=fgets(puffer,81,fp); //Lesen Zeile 1. fgets liest eine Zeile bis zum Zeichen \n, falls dieses bis zum 80. Zeichen gefunden wurde. Diese max. 80 gelesenen Zeichen werden in den Puffer geschrieben, einschließlich \n. Dahinter wird ein String-Abschluss \0 geschrieben, damit die Zeile als string verarbeitet werden kann. Der Zeiger z wird auf die puffer Adresse gesetzt. 2. fgets beendet nach der im 2.Argument angegebenen Zeichenzahl (-1), falls bis dahin das \n Zeichen nicht gefunden wurde. Das letzte Zeichen wird für das Schreiben des \0 Zeichens benötigt. Peter Sobe 19 High-Level-Zugriff: Zeilenweises Lesen 3. fgets liest eine Zeile bis zum Dateiende, falls dieses vor Erreichen des 80. Zeichens bzw. und ohne Finden eines \n erreicht wurde. Die gelesenen Zeichen werden in den Puffer geschrieben, einschließlich \n. Dahinter wird ein String-Abschluss \0 geschrieben, damit die Zeile als String weiter verarbeitet werden kann. 4. Kann nichts mehr gelesen werden, wird der Zeiger z auf die NULL Adresse gesetzt. Die NULL-Adresse wird auch bei einem Lesefehler zurückgegeben. Über die Funktion ferror() lässt sich ein Fehler oder ein Lesen über das Dateiende hinaus abklären. Peter Sobe 20

High-Level-Zugriff: Zeilenweises Schreiben In C wird mit fputs eine Datei zeilenweise geschrieben: #include <stdio.h> void main() { char c; FILE *fp; char zeile[81]= Das ist eine Zeile! ; char *z=zeile; fp = fopen( c:\\dat.txt, w ); fputs(z, fp);... fclose(fp); //Schreiben Zeile Peter Sobe 21 High-Level-Zugriff: Formatiertes Lesen einer Datei In C wird mit fscanf eine Datei formatiert gelesen: #include <stdio.h> void main() { char c; FILE *fp; int ao; struct abt{char nr[5]; char nam[20]; char leit[7]; a; fp = fopen( c:\\dat.txt, r ); ao=fscanf(fp, %s%s%s, a.nr,a.nam,a.leit); //Lesen Anzahl von Objekten nr,nam,leit // Rückkehrwert ao ist die Anzahl gelesener Obj. // Rueckkehrwert 1 bei EOF... fclose(fp); Peter Sobe 22

High-Level-Zugriff: Formatiertes Schreiben In C wird mit fprintf eine Datei formatiert geschrieben: #include <stdio.h> void main() { char c; FILE *fp; int ao; struct abt{char nr[5]; char nam[20]; char leit[7]; a={ 111, Produktion, 4531 ; fp = fopen( c:\\dat.txt, w ); ao=fprintf(fp, %s%s%s, a.nr,a.nam,a.leit); //Schreiben von Objekten nr,nam,leit // Rückkehrwert ao ist die Anzahl geschriebener Obj. // Rueckkehrwert 1 bei EOF... fclose(fp); Peter Sobe 23 High-Level-Zugriff: Zugriff auf Binärdateien (1) Universelle Funktionen fread, fwrite: Lesen mit fread: #include <stdio.h> void main() { FILE *fp; fp = fopen( c:\\dat.bin, r ); n_gelesen=fread(puffer_ptr, laenge, anz_elemente, fp ); fclose(fp); Es werden laenge*anz_elemente Bytes aus der Datei in den Puffer (puffer_ptr) gelesen. Die Anzahl gelesener Elemente wird zurückgegeben. Peter Sobe 24

High-Level-Zugriff: Zugriff auf Binärdateien (2) Universelle Funktionen fread, fwrite: Schreiben mit fwrite: #include <stdio.h> void main() { FILE *fp; fp = fopen( c:\\dat.bin, w ); n_geschrieben=fwrite(puffer_ptr, laenge, anz_elemente, fp ); fclose(fp); Es werden laenge*anz_elemente Bytes aus dem Puffer (puffer_ptr) in die Datei geschrieben. Die Anzahl geschriebener Elemente wird zurückgegeben. Peter Sobe 25 High-Level-Zugriff: Positionieren in Dateien (1) Zurücksetzen einer Datei an den Anfang: void rewind(file *fp); fp ist dabei das Datei-Handle. Die Funktion rewind() erzeugt bei Ausführung keinen Rückkehrwert. Positionieroperation auf eine bestimmte Position: int fseek(file *fp, long anz, int pos_mode); Der Parameter anz gibt die Anzahl der Bytes relativ zu pos_mode an, um die der Dateizeiger bewegt werden soll. Für pos_mode gibt es nur drei Möglichkeiten: 0 für Dateianfang (Konstante SEEK_SET), 1 für aktuelle Position (Konstante SEEK_CURR) und 2 für Dateiende (SEEK_END). Bei fehlerfreier Ausführung ist der Rückkehrwert 0, sonst ungleich 0. Peter Sobe 26

High-Level-Zugriff: Positionieren in Dateien (2) Beispiel: fseek(fp, -10L, 1); Der Dateizeiger wird ab der aktuellen Zeigerposition (1) um insgesamt 10 Bytes zurückgesetzt. Mit der Funktion long ftell(file *fp) wird der aktuelle Dateizeiger relativ zum Dateianfang (als Anzahl der Bytes ) zurückgegeben. ftell sollte wegen der unterschiedlichen Darstellung des Zeilenendes nur im Binärmodus verwendet werden. Peter Sobe 27 Low-Level Verarbeitung von Dateien Unterschied der Zugriffsarten: Anwendungsprogramm Standardbibliothek High-Level- Zugriffsfunktionen: Vielzahl von Funktionen, E/A-gepuffert, komfortabel Betriebssystem, z.b. Windows, Unix Low-Level- Zugriffsfunktionen: Minimalumfang, einfach, schnell, aber wenig komfortabel Peter Sobe 28

Low-Level Verarbeitung von Dateien Eine Datei wird mit der Funktion int open(const char *path, int flags, int zugriffsrechte) geöffnet. path ist dabei der Pfad- und Dateiname. Mit flags werden Zugriffsflags angegeben. Mit dem bitweisen ODER können folgende Konstanten gesetzt sein: O_APPEND neu geschriebene Daten werden angehängt O_CREAT wenn die Datei nicht existiert, wird sie mit dem im Parameter mode angegebenen Eigenschaften erzeugt O_TRUNC wenn die Datei existiert, wird der Inhalt überschrieben O_BINARY und O_TEXT sind zusätzlich möglich Den Parameter zugriffsrechte setzt Zugriffsrechte (insg. 9 Bits). Peter Sobe 29 Low-Level Verarbeitung von Dateien Zugriffsrechte: Flags Lesen (r ), Schreiben (w) und Ausführen (x) für den Eigentümer (u - user), für die Gruppe (g - group) und für den Rest (o others). Kodierung in 9-Bits: user group others r w x r w x r w x Beispiel: 1 1 1 1 0 0 0 0 0 bedeutet, dass der Eigentümer alles darf, die Nutzer in der gleichen Gruppe dürfen die Datei zum Lesen öffnen. Zugriffsrechte werden oft durch Oktalzahlen angeben. Eine Stelle fasst 3 Bits zusammen. Im Beispiel ergibt sich 740. Peter Sobe 30

Low-Level Verarbeitung: Öffnen open liefert den Dateideskriptor, eine Zahl, zurück. Beispiel: outfile = open(pfad, O_WRONLY O_CREAT O_TRUNC, 0777) Die Oktalzahl O777 setzt alle Zugriffsrechte. Der übergebene Dateideskriptor (hier outfile) ist eine natürliche Zahl ab 5 und bildet den Rückkehrwert von open. Die Werte 0..4 sind reserviert für 0 stdin, 1 stdout, 2 stderror, 3 stdaux, 4 stdprn. Ein Rückkehrwert von 1 signalisiert einen Fehler. Peter Sobe 31 Low-Level Verarbeitung: Close und Read Eine Datei wird mit der Funktion int close(int filedes) geschlossen. Für den Parameter filedes tritt dann der Deskriptor, d.h. z.b. fileout=5. Ein Rückkehrwert von 0 ist in Ordnung. Ein Wert 1 signalisiert einen Fehler. Das Lesen einer Bytefolge mit der Länge len von der Datei mit dem Deskriptor file_descriptor wird mit der Funktion int read(int file_descriptor, void *buf, unsigned len) ausgeführt, wobei die Bytefolge in den Hauptspeicher ab der Adresse buf geschrieben wird. Der Rückkehrwert von read ist die Anzahl der gelesenen Bytes: nbytes = read(infile, rwbuf, 1024); Im Fehlerfall ist der Rückkehrwert 1. Peter Sobe 32

Low-Level Verarbeitung: Write Das Schreiben einer Bytefolge der Länge len wird mit der Funktion int write(int file_descriptor, void *buf, unsigned len) aufgerufen. Die zu schreibende die Bytefolge wird dem Hauptspeicher ab der Adresse buf entnommen. Der Rückkehrwert von write ist die tatsächlich geschriebene Anzahl der Bytes. Beispiel: int wlen = write(outfile, wbuf, 1024) ; Im Fehlerfall ist der Rückkehrwert 1. Peter Sobe 33 Low-Level Verarbeitung: Write Beispiel: Das Schreiben einer Fehlermeldung errmsg in die Datei stderr wird mit dem Aufruf write(2, errmsg, strlen(errmsg)); durchgeführt, wobei errmsg wie folgt deklariert ist: char *errmsg ="\ndatei konnte nicht geoeffnet werden."; Peter Sobe 34

Low-Level Verarbeitung: Positionieren Funktion lseek: Vergleichbar mit der High-Level-Zugriffsfunktion fseek, hier aber mit Bezug auf File-Deskriptor Parameter: long lseek(int fd, long offset, int origin); fd: File-Deskriptor einer geöffneten Datei offset: Position, an welcher der nächste Zugriff stattfinden soll origin: Ausgangspunkt der offset-betrachtung 0- von Beginn, 1- von aktueller Position, 2- vom Ende Peter Sobe 35 Verschiedene Funktionen für die Dateiarbeit In C werden für Hilfszwecke rund um die Datei- Verarbeitung eine Reihe von Funktionen angeboten: Das sind vor allem Funktionen für die Arbeit mit Verzeichnissen und Laufwerken das Umbenennen und Löschen von Dateien/Ordnern das Positionieren des Dateizeigers und die Fehlerbehandlung Peter Sobe 36

Funktionen für die Arbeit mit Verzeichnissen (1) Das aktuelle Laufwerk kann man mit der Funktion void _dos_getdrive(unsigned *lw) ermitteln. Beispiel: unsigned d; _dos_getdrive(&d); //ermittelt aktuelles LW printf("das aktuelle LW ist: %c\n", d + 'A' - 1); Es wird die aktuelle Laufwerks-Nummer zurückgegeben, A=1, B=2, C=3,... Nur in Windows möglich! Andere Betriebssysteme benutzen keine Laufwerke. Peter Sobe 37 Funktionen für die Arbeit mit Verzeichnissen (2) Das aktuelle Laufwerk kann man mit der Funktion void _dos_setdrive(unsigned lw,unsigned *anz) neu gesetzt werden. Beispiel: unsigned n; _dos_setdrive(3,&n); //setzt aktuelles LW auf C printf( Es gibt insgesamt %d LW \n",n); Es wird die max. Anzahl von logischen LW-Nummern zurückgegeben. Peter Sobe 38

Funktionen für die Arbeit mit Verzeichnissen (3) UNIX-Dateisysteme (POSIX Standard) Ermitteln des aktuellen Arbeitsverzeichnisses: char *getcwd(char *buf, size_t size); Schreibt das aktuell eingenommene Verzeichnis in die Zeichenkette buf mit maximal size Zeichen. Bei Erfolg wird der Zeiger buf zurückgegeben, anderenfalls NULL. Die Variable errno zeigt den Grund des Fehlers an, z.b. ERANGE wenn size zu kurz ist. Setzen: int chdir(const char *pfad); // gibt 0 bei Erfolg zurück Peter Sobe 39 Durchlaufen von Verzeichnissen Mit den Funktionen unsigned _findfirst(const char *pfad, struct _finddata_t *fblk) und unsigned _findnext( struct _finddata_t *fblk) kann der Inhalt eines Verzeichnisses schrittweise gelesen werden. Der pfad-parameter ist die Adresse eines Pfades (z.b. c:\temp)..), der Parameter fblk ist die Adresse einer Strukturvariablen, die dann die Resultate enthält (z.b.namen der Datei, Größe in Bytes, Änderungsdatum und zeit). Peter Sobe 40

Beispiel: Durchlaufen von Verzeichnissen _finddata_t filesfound; intptr_t f = _findfirst("c:\\temp\\*.*",&filesfound); //Alle Dateien in C:\TEMP if ( f!= -1L ) { do { if (!( filesfound.attrib & _A_SUBDIR ) ) { //Verzeichnis ausschliessen printf("%s %Iu\n",filesfound.name,filesfound.size); while ( _findnext(f,&filesfound)==0 ); //Nächste Datei _findclose(f); //Handle schliessen Peter Sobe 41 Funktionen für die Arbeit mit Verzeichnissen Das Anlegen (Erzeugen) eines Ordners erfolgt mit der C- Funktion int mkdir(cont char *pfad). Bei fehlerfreier Ausführung ist der Rückkehrwert 0, sonst 1. char pfad[30]= c:\\temp\\neu ; if (mkdir(pfad)) printf( \nfehler! ); else printf( \nordner erfolgreich erzeugt ); Peter Sobe 42

Umbenennen und Löschen von Dateien/Ordnern Das Umbenennen einer Datei/ eines Ordners erfolgt mit der C- Funktion int rename(const char *alt, const char *neu). Die Parameter alt und neu können vollständige Pfadangaben enthalten. Beide Pfade müssen gleich sein. Der Zugriff auf die Datei/Ordner muss nach Zugriffsrechten erlaubt sein. Bei fehlerfreier Ausführung ist der Rückkehrwert 0, sonst 1. char a[20]= c:\\temp\\x.txt ; char n[20]= c:\\temp\\y.txt ; // bei einem Ordner texte würde der Pfad z.b. sein // char a[20]= c:\\temp\\texte ; if (! rename(a,n)) printf( \nfehler! ); Peter Sobe 43 Löschen von Dateien/Ordnern Das Löschen einer Datei erfolgt mit der C-Funktion int remove(const char *name). Gesperrte Dateien: Die im Parameter angegebene Datei darf zu diesem Zeitpunkt nicht in Nutzung sein, d.h. muss geschlossen sein. Bei fehlerfreier Ausführung ist der Rückkehrwert 0, sonst 1. char datei[20]= c:\\temp\\x.txt ; if (! remove(datei)) printf( \nfehler! ); else printf( \ndatei erfolgreich gelöscht ); Peter Sobe 44

Löschen von Dateien/Ordnern Das Löschen eines Ordners erfolgt mit der C-Funktion int rmdir(const char *name). Der im Parameter angegebene Ordner muss zu diesem Zeitpunkt leer sein, er darf nicht das aktuelle Arbeitsverzeichnis sein und nicht das Stammverzeichnis des LW. Bei fehlerfreier Ausführung ist der Rückkehrwert 0, sonst 1. char ordner[20]= c:\\temp\\texte ; if (! rmdir(ordner)) printf( \nfehler! ); else printf( \nordner erfolgreich gelöscht ); Peter Sobe 45