# Programmation POSIX/Lecture et écriture de fichiers

Processus
* Processus
* Processus légers
* Signaux
Fichiers
* Lecture et écriture
* Verrouillage
* Tubes
* Opérations sur les fichiers
Annexes
* Index
* Ressources
Processus
* Processus
* Processus légers
* Signaux
Fichiers
* Lecture et écriture
* Verrouillage
* Tubes
* Opérations sur les fichiers
Annexes
* Index
* Ressources
Livre
[ Modifier le sommaire ]
Nous allons ici expliquer comment accéder au contenu des fichiers : comment ouvrir et fermer un fichier, lire et écrire dans un fichier, etc. Pour pouvoir manipuler le contenu d'un fichier, il faut utiliser un descripteur de fichier ouvert. Ce descripteur est un simple entier qui sera obtenu en utilisant la fonction d'ouverture de fichier et qui sera ensuite utilisé par toutes les autres fonctions manipulant les fichiers.

## Ouverture

L'appel système open convertit un chemin vers un fichier en descripteur de fichier ouvert. Ce qui revient suivant les options fournies à créer un nouveau fichier ou à en ouvrir un existant en lecture et/ou en écriture. Les valeurs possibles pour options sont des ou binaire entre O_RDONLY, O_WRONLY ou O_RDWR et une ou plusieurs des constantes symboliques suivantes :
* O_CREAT, créé le fichier s'il n'existe pas. Les droits du fichier sont ceux spécifiés dans l'argument mode ;
* O_EXCL, à utiliser en conjonction avec O_CREAT, provoque l'échec de l'appel si le fichier existe déjà ;
* O_TRUNC, si le fichier existe, est régulier et est ouvert en écriture, le fichier est tronqué à la longueur nulle (il est vidé) ;
* O_APPEND, le fichier est ouvert en mode ajout : la tête de lecture est placée à la fin du fichier.
(Il existe d'autres options que nous ne détaillerons pas ici)
L'argument mode défini les droits du fichier lorsque celui ci est créé par l'appel à open. Des constantes symboliques représentant les droits possibles sont définies, il est cependant beaucoup plus simple de les spécifier en utilisant une valeur en octal.
L'appel système creat est équivalent à open avec les options: O_CREAT | O_WRONLY | O_TRUNC.

## Fermeture

L'appel système close ferme le descripteur de fichier ouvert fd.

### Exemple ouverture/fermeture
## Lecture

L'appel système read lit au plus nombre octets depuis le descripteur de fichier fd et les place dans le buffer. En cas d'erreur, read renvoie -1, sinon le nombre d'octets réellement lus est renvoyé. L'argument nombre peut être nul auquel cas rien n'est lu et read renvoie 0, par contre il doit être inférieur à SSIZE_MAX.
Remarque : Il est beaucoup plus intéressant, au niveau des performances, de lire de grandes quantités de données et de minimiser le nombre d'appels à read que de lire le fichier petits bouts par petits bouts (le pire étant de lire le fichier caractère par caractère).

## Écriture

L'appel système write écrit au plus nombre octets dans le descripteur de fichier ouvert fd. Le nombre d'octets réellement écrit est renvoyé si l'appel réussit, sinon write renvoie -1.
Lorsqu'un appel à read est effectué après un appel à write, les données venant d'être écrites sont renvoyées.

### Exemple lecture/écriture

Le programme suivant utilise tout ce que l'on a vu précédemment pour réaliser un programme permettant de copier un fichier (tel l'utilitaire Unix cp). Le programme prend deux arguments : le fichier source et le fichier destination et recopie le premier dans le second en utilisant les fonctions read, write et un buffer de 100 octets (en fait de 100 caractères, en supposant que le type caractère correspond bien à un octet).

## Déplacement

L'appel système lseek permet de modifier la position courante dans un fichier en la déplaçant d'une certaine quantité à partir d'un point de départ. Ce point de départ peut être :
* SEEK_SET, le déplacement est effectué à partir du début du fichier ;
* SEEK_CUR, le déplacement est effectué à partir de la position courante ;
* SEEK_END, le déplacement est effectué à partir de la fin du fichier.
En particulier lseek(fd, 0, SEEK_SET) permet de se positionner au début du fichier et lseek(fd, 0, SEEK_END) à la fin.
La valeur renvoyé par lseek est le déplacement réellement effectué en nombre d'octets (ainsi en se positionnant au début puis à la fin du fichier, il est possible de calculer la taille de ce fichier).