• 28 Mars 2024, 13:49:07


Auteur Sujet: Les fonctions de gestion des fichiers  (Lu 23994 fois)

0 Membres et 2 Invités sur ce sujet

Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Les fonctions de gestion des fichiers
« le: 21 Septembre 2009, 16:10:08 »
LES FICHIERS ET LES FONCTIONS ASSOCIÉES

1 GÉNÉRALITÉS

Un 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.
Code: (pawn) [Sélectionner]
#include <file>
2 OUVERTURE D'UN FICHIER

Pour 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 :
Code: (pawn) [Sélectionner]
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à) :
Code: (pawn) [Sélectionner]
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 FICHIER

La 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 :
Code: (pawn) [Sélectionner]
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 FICHIER

Le 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 :
Code: (pawn) [Sélectionner]
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 :
Code: (pawn) [Sélectionner]
fseek (Fic, 5, seek_current);
Revenir de 7 octets en arrière :
Code: (pawn) [Sélectionner]
fseek (Fic, -7, seek_current);
Aller au 18ème octet du fichier
Code: (pawn) [Sélectionner]
fseek (Fic, 18, seek_start);
Aller à l'avant-dernier octet du fichier :
Code: (pawn) [Sélectionner]
fseek (Fic, -1, seek_end);
Aller au début du fichier :
Code: (pawn) [Sélectionner]
fseek (Fic);ou
Code: (pawn) [Sélectionner]
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
Code: (pawn) [Sélectionner]
fseek (Fic, 18, seek_start);renverra 18 et
Code: (pawn) [Sélectionner]
fseek (Fic, 0, seek_end); //Dernier octet du fichierrenverra la taille du fichier.

5 LECTURE DANS UN FICHIER

Une 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 CHAINES

Pour lire une chaîne de caractères, on utilise la fonction fread :
Code: (pawn) [Sélectionner]
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 BRUTES

Il est possible de lire des données binaire (brutes) dans un fichier au moyen de la fonction fblockread :
Code: (pawn) [Sélectionner]
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 :
Code: (pawn) [Sélectionner]
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 LECTURE

Il est aussi possible de ne lire qu'un seul caractère dans un fichier ouvert au moyen de la fonction fgetchar :
Code: (pawn) [Sélectionner]
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 FICHIER

L'écriture dans un fichier suis les mêmes principes que la lecture.

6.1 ÉCRITURE DE CHAINES

Pour écrire une chaîne de caractères, on utilise la fonction fwrite :
Code: (pawn) [Sélectionner]
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 BRUTES

Il est possible d'écrire des données binaire (brutes) dans un fichier au moyen de la fonction fblockwrite :
Code: (pawn) [Sélectionner]
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 :
Code: (pawn) [Sélectionner]
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 00

6.3 AUTRE FONCTION D'ÉCRITURE

Il est aussi possible de n'écrire qu'un seul caractère dans un fichier ouvert au moyen de la fonction fputchar :
Code: (pawn) [Sélectionner]
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 FICHIERS

7.1 SUPPRESSION D'UN FICHIER
Il est possible de supprimer un fichier au moyen de la fonction fremove :
Code: (pawn) [Sélectionner]
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 FICHIER

Il est possible de récupérer la taille d'un fichier ouvert grâce à la fonction flength :
Code: (pawn) [Sélectionner]
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
« Modifié: 01 Octobre 2012, 19:05:22 par GtaManiac »
Courtesy of GtaManiac


Hors ligne R@f

  • *
  • GTAOnline Addict
  • Messages: 4655
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #2 le: 21 Septembre 2009, 16:48:21 »
Nice one Syg ;)

++
R@f

Hors ligne cristab

  • *
  • Messages: 8379
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #3 le: 21 Septembre 2009, 16:56:17 »
Merci pour le Tuto tres bien expliquer
pas d'aide en PM, vous êtes sur un forum est il me semble que vous êtes la pour avoir de l'aide donc pourquoi MP une seul personne qui ne vous répondra pas alors qu'il y a plein de membre ici

Hors ligne FuSion

  • Pawn coder
  • *
  • Grand Banditisme
  • for(new i = 0; i < INFINI; i++)
  • Messages: 888
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #4 le: 21 Septembre 2009, 18:00:26 »
Joli tuto, surtout pour creer un petit système de compte  :laugh

GG

++
FS'

Hors ligne cristab

  • *
  • Messages: 8379
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #5 le: 21 Septembre 2009, 18:07:50 »
exactement justement je tente de creer une include pour faciliter l'utilisation de ceci mais j'aurais une question ^^

apparement la fonction "io_append" cree aussi le fichier si il n'existe pas est ce normale ou je me melange les pinceaux ?


EDIT desoler je me melanger les pinceaux et apparement c'est avec cette fonction que je buche un peu "if(fexist(Nom))"
« Modifié: 21 Septembre 2009, 18:10:25 par cristab »
pas d'aide en PM, vous êtes sur un forum est il me semble que vous êtes la pour avoir de l'aide donc pourquoi MP une seul personne qui ne vous répondra pas alors qu'il y a plein de membre ici

Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #6 le: 21 Septembre 2009, 18:56:22 »
Effectivement, j'ai oublié de parler de la fonction fexist.

Elle permet de vérifier si un fichier existe ou pas.
Elle renvoie true si le fichier existe, false sinon.

Dans l'absolu cette fonction n'est pas nécessaire, il suffit d'ouvrir systématiquement le fichier avec io_readwrite (qui fonctionne dans tous les cas).
Ensuite, il faut tester lors des lectures que l'on a bien lu quelque chose :
if (fread (Fic, Chaine) != 0)
{
   printf ("Lecture OK\n");
}
else
{
   printf ("Fichier vide\n");
}

Sinon, il se peut que le mode io_append crée le fichier s'il n'existe pas, je n'ai pas testé spécifiquement.
De toutes façons, les fichiers de données sont lus ou écrits depuis le début, il est très rare qu'on aie à y ajouter des données donc le mode io_append n'est que très peu utilisé.

++
Syg

Courtesy of GtaManiac

Hors ligne cristab

  • *
  • Messages: 8379
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #7 le: 21 Septembre 2009, 19:07:40 »
donc en gros un truc du genre suffit a écrire dans un fichier


ecrfic(Nom[],contenue[])
{
new File:Fic;
Fic = fopen (Nom, io_readwrite);
fwrite(Fic,contenue);
fclose (Fic);
}
pas d'aide en PM, vous êtes sur un forum est il me semble que vous êtes la pour avoir de l'aide donc pourquoi MP une seul personne qui ne vous répondra pas alors qu'il y a plein de membre ici

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #8 le: 21 Septembre 2009, 20:34:43 »
GG sim, mais pour la case inssensitive je ne pense pas que ce soit vrai avec samp car quand je me logue sur un server avec mon pseudo Sasuke78200 et sasuke78200 ce n' est pas le meme compte pourtant ce sont les meme extension =)



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne cristab

  • *
  • Messages: 8379
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #9 le: 21 Septembre 2009, 20:43:36 »
Syg mon petit sasuke  :P
pas d'aide en PM, vous êtes sur un forum est il me semble que vous êtes la pour avoir de l'aide donc pourquoi MP une seul personne qui ne vous répondra pas alors qu'il y a plein de membre ici

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #10 le: 21 Septembre 2009, 21:46:17 »
Oops, a force de voir sim poster lui est rester bloquer dans mon crane xD


Syg !!



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne S!m

  • *
  • Messages: 2341
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #11 le: 22 Septembre 2009, 01:27:06 »
Salut,

très beau tuto Syg, bravo, :cheers
sinon pour le mode io_readwrite, j'avais cru comprendre qu'il ne permet pas d'écrire, cette information serait donc fausse et je pourrais utiliser cette fonction pour aller modifier une partie du fichier?

++Sim++





Hors ligne [viruz]rider_77

  • *
  • Mafioso
  • C/C++ programming
  • Messages: 2154
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #12 le: 22 Septembre 2009, 02:06:42 »
C'est cool que t'aies trouvé du temps Syg, parce que comme tuto on peut pas demander de mieux expliquer.
GG.

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Re : Les fonctions de gestion des fichiers
« Réponse #13 le: 22 Septembre 2009, 07:50:26 »
Salut,

très beau tuto Syg, bravo, :cheers
sinon pour le mode io_readwrite, j'avais cru comprendre qu'il ne permet pas d'écrire, cette information serait donc fausse et je pourrais utiliser cette fonction pour aller modifier une partie du fichier?

++Sim++

Béh c' est un peu bête car en analysant la ligne on voit tres bien le write ( pour ecrire ) et aussi un read ( pour lire ) donc avec ce mode on peu lire et ecrire dan un fichier



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Re : Les fonctions de gestion des fichiers
« Réponse #14 le: 22 Septembre 2009, 14:00:49 »
GG simSyg, mais pour la case inssensitive je ne pense pas que ce soit vrai avec samp car quand je me logue sur un server avec mon pseudo Sasuke78200 et sasuke78200 ce n' est pas le meme compte pourtant ce sont les meme extension =)
La comparaison de pseudo se fait avec strcmp qui possède un flag qui permet de la rendre case insensitive (sous Windows ET sous Linux).
Concernant les noms de fichiers, c'est le système de fichier (donc l'OS) présent sur la machine qui décide.
Sinon, il existe des fonctions pour mettre toutes les lettres d'une chaîne en majuscule ou en minuscule et ainsi éliminer le problème des fichiers qui ont le nom des joueurs.

sinon pour le mode io_readwrite, j'avais cru comprendre qu'il ne permet pas d'écrire, cette information serait donc fausse et je pourrais utiliser cette fonction pour aller modifier une partie du fichier?
Tout est dans le nom du mode d'accès : readwrite comme l'a dit sasuke78200
Ce mode peut être utilisé dans tous les cas et avec la fonction fseek, il est possible d'aller lire et écrire n'importe où dans le fichier.
Mais attention, l'écriture au milieu d'un fichier remplace les données qui sont déjà présente avec le nouvelles données, il n'est pas possible, de cette façon, d'insérer des données au milieu d'un fichier, seulement à la fin.

donc en gros un truc du genre suffit a écrire dans un fichier
ecrfic(Nom[],contenue[])
{
new File:Fic;
Fic = fopen (Nom, io_readwrite);
fwrite(Fic,contenue);
fclose (Fic);
}
Oui, mais en bon programmeur tu devrais quand même tester les codes retour des fonctions (au cas très improbable où ça ne fonctionnerait pas).

++
Syg
Courtesy of GtaManiac