LES FICHIERS ET LES FONCTIONS ASSOCIÉES1 GÉNÉRALITÉSUn fichier est un ensemble de données plus ou moins structurées stocké sur un support permanent (il est toutefois possible de créer de fichiers en mémoire mais l'intérêt en PAWN reste limité).
Un fichier peut être vu comme une boite avec des cases où chaque case est numérotée (à partir de 0) et contient un octet.
De ce fait, les fonctions de gestion de fichier permettent d'ouvrir la boite, de se positionner sur une case donnée, de récupérer le contenu d'une ou plusieurs cases et de refermer la boite.
On considère généralement deux types de fichiers : les fichier textes (que l'on peut ouvrir directement avec notepad par exemple) et les fichiers binaires.
Mais les fichiers textes ne sont rien d'autres que des fichiers binaires ne contenant (presque) que des caractères lisibles.
Un fichier est identifié par son nom.
Exemples :
VEHICULES.TXT, SPAWN.DAT, TEAMS.BANNIES.BIN, ...Une fois ouvert, un fichier est identifié par une variable de type
File.
Remarques : - L'extension n'est pas obligatoire,
- Sous Windows, il n'y a pas de différence entre les miniscules et les majuscules (case insensitive). Les fichiers toto.txt, TOTO.txt ou ToTo.TXT ne seront qu'un seul et même fichier. Sous Linux, les fichiers cités précédemment seront trois fichiers distincts. Il est important d'avoir ceci à l'esprit car un script qui accède à des fichiers peut fonctionner parfaitement sous Windows et ne plus fonctionner du tout sur un serveur Linux.
Sous SAMP, les fichiers sont stockés dans le sous-répertoires scriptfiles (ou un des ses sous-répertoire) contenu dans le répertoire du serveur et il n'est possible de les stocker ailleurs.
Pour pouvoir utiliser les fonctions de gestions de fichiers, il faut inclure
file.inc dans le script.
#include <file>
2 OUVERTURE D'UN FICHIERPour pouvoir utiliser les données contenues dans un fichier, il faut tout d'abord l'ouvrir.
L'ouverture d'un fichier se fait au moyen de la fonction
fopen :
native File:fopen(const name[], filemode: mode = io_readwrite);
Le premier paramètre de cette fonction est le nom du fichier que l'on veut ouvrir.
Le deuxième paramètre indique comment va être ouvert le fichier.
Ce paramètre peut prendre une des valeurs suivante :
io_read -> Ouverture d'un fichier existant en lecture seule. Il ne sera pas possible d'écrire dans le fichier.
io_write -> Création d'un fichier qui n'existe pas pour écriture. Il ne sera pas possible de lire dans le fichier.
io_readwrite -> Ouverture d'un fichier existant en lecture/écriture ou création d'un nouveau fichier.
io_append -> Ouverture d'un fichier existant en écriture seule. Il ne sera pas possible de lire dans le fichier.
Remarque :Dans la plupart des cas, on utilisera
io_readwrite qui, de plus, est la valeur par défaut pour ce paramètre
La valeur de retour de
fopen est de type
File et sera ensuite utilisée pour accéder au fichier.
On appellera dorénavant cette valeur le handle du fichier.
Si l'ouverture échoue (fichier introuvable, caractère incorrect dans le nom du fichier, ...), la valeur de retour vaudra 0.
Exemple qui crée un fichier vide dans le répertoire scriptfile (ou ouvre le fichier si il existe déjà) :
new File:MonFichier;
MonFichier = fopen ("toto.txt", io_readwrite);
if (MonFichier != File:0) // On ne compare pas directement à 0 sinon ceci provoque un warning
{
/* On ferme le fichier */
fclose (Monfichier);
}
else
{
printf ("Erreur d'ouverture du fichier\n");
}
3 FERMETURE DU FICHIERLa fermeture du fichier a pour effet de libérer le fichier et d'écrire physiquement sur le disque les données qui se trouvent éventuellement dans le cache du disque.
La fermeture d'un fichier se fait au moyen de la fonction de la fonction
fclose :
native bool:fclose(File: handle);
Le paramètre de cette fonction est un handle de fichier valide.
ATTENTION : Ne pas utiliser fclose avec handle invalide.Cette fonction retourne
true (1) lorsque la fermeture a été effectuée correctement et
false (0) dans le cas contraire.
ATTENTION : Ne pas utiliser le code retour de cette fonction, ceci n'a pas été vérifié (cf wiki SAMP).4 POSITIONNEMENT DANS LE FICHIERLe positionnement dans un fichier est appelé index de lecture/écriture. Ceci correspond à la position de l'octet qui sera lu ou écrit.
Chaque lecture ou écriture incrémente l'index de lecture/écriture du nombre d'octet lu ou écrit.
Après ouverture, l'index de lecture/ecriture est positionné au début du fichier ou à la fin si le fichier est ouvert avec l'option
io_append.
Il est possible de déplacer l'index sans faire de lecture ou d'écriture au moyen de la fonction
fseek :
native fseek(File: handle, position = 0, seek_whence: whence = seek_start);
Le premier paramètre de cette fonction est le handle sur un fichier ouvert.
Le deuxième paramètre contient la position relative (donc positive ou négative) en fonction du troisième paramètre.
Le troisième paramètre contient la position de référence et peut prendre une des trois valeurs suivantes :
seek_start -> Début du fichier
seek_current -> Position courante
seek_end -> Fin du fichier
Exemples :
Sauter 5 octets dans le fichier :
fseek (Fic, 5, seek_current);
Revenir de 7 octets en arrière :
fseek (Fic, -7, seek_current);
Aller au 18ème octet du fichier
fseek (Fic, 18, seek_start);
Aller à l'avant-dernier octet du fichier :
fseek (Fic, -1, seek_end);
Aller au début du fichier :
fseek (Fic);
ou
fseek (Fic, 0, seek_start);
Le valeur de retour de
fseek donne le déplacement effectué dans le fichier en octet.
Par exemple, si l'index de lecture est positionné au début du fichier alors
fseek (Fic, 18, seek_start);
renverra 18 et
fseek (Fic, 0, seek_end); //Dernier octet du fichier
renverra la taille du fichier.
5 LECTURE DANS UN FICHIERUne fois le fichier ouvert par la fonction
fopen, il est possible de lire les données qu'il contient.
Il existe trois type de lecture dans SAMP : la lecture de chaînes de caractères, la lecture de données brutes et la lecture d'un caractère.
5.1 LECTURE DE CHAINESPour lire une chaîne de caractères, on utilise la fonction
fread :
native fread(File: handle, string[], size = sizeof string, bool: pack = false);
Le premier paramètre de cette fonction est le handle sur un fichier ouvert en lecture ou en lecture/écriture.
Le deuxième paramètre est une variable de type tableau qui recevra les données lues.
Le troisième paramètre correspond à la taille maximale que peut contenir le tableau passé en deuxième paramètre.
Le quatrième paramètre indique que les données lues seront compactées (les données compactées ne sont pas l'objet de ce tutoriel, il est préférable de laisser ce paramètre à
false)
La valeur de retour de
fread correspond au nombre d'octets effectivement lus dans le fichier. Si la valeur de retour est 0, aucune lecture n'a été faîte.
ATTENTION : Ce nombre ne correspond jamais à la taille de la chaîne. Il est donc peu recommandé de s'en servir pour connaître la taille de la chaîne lue.5.2 LECTURE DE DONNÉES BRUTESIl est possible de lire des données binaire (brutes) dans un fichier au moyen de la fonction
fblockread :
native fblockread(File: handle, buffer[], size = sizeof buffer);
Le premier paramètre de cette fonction est le handle sur un fichier ouvert en lecture ou en lecture/écriture.
Le deuxième paramètre est une variable de type tableau qui recevra les données lues.
Le troisième paramètre correspond au nombre d'éléments du tableau qu'on veut lire.
La valeur de retour de la fonction donne le nombre d'éléments lus.
Remarque :Ici, on parle bien d'éléments d'un tableau et non pas d'octets. En Pawn, sous SAMP, un élément fait 4 octets.
Exemple :
new File:Fic;
new Tableau[5];
Fic = fopen ("TOTO.BIN", io_readwrite);
if (Fic != File:0)
{
/* Lecture de 3 éléments */
fblockread (Fic, Tableau, 3));
fclose (Fic);
}
else
{
printf ("Erreur d'ouverture du fichier TOTO.TXT\n");
}
5.3 AUTRE FONCTION DE LECTUREIl est aussi possible de ne lire qu'un seul caractère dans un fichier ouvert au moyen de la fonction
fgetchar :
native fgetchar(File: handle, value, bool: utf8 = true);
Le premier paramètre de cette fonction est le handle sur un fichier ouvert en lecture ou en lecture/écriture.
Le deuxième paramètre est une variable qui recevra la valeur du caractère lu.
Le troisième paramètre indique si l'on est en ANSI (1 octet par caractère) ou en UTF8 (2 octets par caractère).
Remarque :Pour les langues comme le français ou l'anglais, il est préférable de mettre ce paramètre à
false.
La valeur de retour de
fgetchar n'est pas documentée et ne semble correspondre à rien, il est plus prudent de ne pas s'en servir.
6 ÉCRITURE DANS UN FICHIERL'écriture dans un fichier suis les mêmes principes que la lecture.
6.1 ÉCRITURE DE CHAINESPour écrire une chaîne de caractères, on utilise la fonction
fwrite :
native fwrite(File: handle, const string[]);
Le premier paramètre de cette fonction est le handle sur un fichier ouvert en écriture ou en lecture/écriture.
Le deuxième paramètre est une variable de type tableau qui contient la chaîne à écrire.
La valeur de retour de
fwrite correspond au nombre d'octets effectivement écrits dans le fichier. Si la valeur de retour est 0, aucune ecriture n'a été faîte.
ATTENTION : Ce nombre ne correspond jamais à la taille de la chaîne à écrire.6.2 ÉCRITURE DE DONNÉES BRUTESIl est possible d'écrire des données binaire (brutes) dans un fichier au moyen de la fonction
fblockwrite :
native fblockwrite(File: handle, const buffer[], size = sizeof buffer);
Le premier paramètre de cette fonction est le handle sur un fichier ouvert en écriture ou en lecture/écriture.
Le deuxième paramètre est une variable de type tableau qui contient les données à écrire.
Le troisième paramètre correspond au nombre d'éléments du tableau qu'on veut écrire dans le fichier.
La valeur de retour de la fonction donne le nombre d'éléments écrits.
Remarque : Ici, on parle bien d'éléments d'un tableau et non pas d'octets. En Pawn, sous SAMP, un élément fait 4 octets.Exemple :
new File:Fic;
new Tableau[5] = {1, 2, 3, 4, 5};
Fic = fopen ("TOTO.BIN", io_readwrite);
if (Fic != File:0)
{
fblockwrite (Fic, Tableau));
fclose (Fic);
}
else
{
printf ("Erreur d'ouverture du fichier TOTO.BIN\n");
}
Voici, en binaire, le contenu du fichier
TOTO.BIN après exécution de l'exemple ci-dessus :
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 006.3 AUTRE FONCTION D'ÉCRITUREIl est aussi possible de n'écrire qu'un seul caractère dans un fichier ouvert au moyen de la fonction
fputchar :
native bool:fputchar(File: handle, value, bool: utf8 = true);
Le premier paramètre de cette fonction est le handle sur un fichier ouvert en écriture ou en lecture/écriture.
Le deuxième paramètre est une variable qui contient la valeur du caractère à écrire.
Le troisième paramètre indique si l'on est en ANSI (1 octet par caractère) ou en UTF8 (2 octets par caractère).
Remarque :Pour les langues comme le français ou l'anglais, il est préférable de mettre ce paramètre à
false.
La valeur de retour de
fputchar vaut
true si l'écriture est correcte,
false sinon.
7 AUTRES FONCTIONS SUR LES FICHIERS7.1 SUPPRESSION D'UN FICHIERIl est possible de supprimer un fichier au moyen de la fonction
fremove :
native bool:fremove(const name[]);
Le premier paramètre de cette fonction est le nom du fichier que l'on veut supprimer.
La valeur de retour de
fremove vaut
true si le fichier a été supprimé correctement,
false sinon.
7.2 TAILLE D'UN FICHIERIl est possible de récupérer la taille d'un fichier ouvert grâce à la fonction
flength :
native flength(File: handle);
Le premier paramètre de cette fonction est le handle sur un fichier ouvert.
La valeur de retour est la taille en octet du fichier.
++
Syg