Les bases pour accéder à un fichier

 

 

 

Tout le monde connait les fonctions fopen(), fread(), ...

Eh bien oubliez les dans le monde de Microsoft.

Vous allez me dire que pour la portabilité, ce n'est pas top ! Je suis d'accord, mais de toute façon, que ce soit vers un système ou un autre, la portabilité d'un programme n'a jamais été chose facile. C'est de bonne guerre, chacun faisant en sorte de fidéliser d'une manière ou d'une autre ses clients...

Les fonctions Microsoft restent similaires à toutes celles que vous avez déjà pu voir (MS-DOS, Unix, Atari ST). Si vous connaissez déjà, ce ne sera pas bien difficile...

Voici donc les fonctions pour gérer les fichiers sous Windows:

Ouvrir un fichier

Il existe une fonction pour ouvrir un fichier, il s'agit de la fonction OpenFile(). Mais je devrais dire "il s'agissait". Si cette fonction est toujours disponible, ce n'est que pour rester compatible avec les versions 16 bits. Préférez plutôt la commande suivante...

Créer/Ouvrir un fichier

La fonction pour créer ou ouvrir un fichier est CreateFile(). Nous sommes en multi-tâches, donc cette fonction va vous permettre de paramètrer le type de partage du fichier avec d'autres applications.

HANDLE CreateFile(

LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile

);

Les paramètres étant:

lpFileName pour le nom du fichier.
DwDesiredAccess pour le type d'accès que l'on désire faire (Dans le cas ou le fichier serait déjà vérouillé par une autre application, le système va alors vérifier que l'autre applicaion autorise ce type d'accès). Les valeurs seront pour:

En lecture:GENERIC_READ,
E n écriture:GENERIC_WRITE,
L es deux:GENERIC_READ | GENERIC_WRITE,
ou NULL pour vérifier l'existance d'un fichier par exemple.

dwShareMode pour indiquer le type d'accès que vous allez autoriser pour les autres applications (Dans le cas où une autre application essayerait d'accèder au fichier pendant que vous travaillez dessus):

Non partagé se sera NULL,
partagé en lecture:FILE_SHARE_READ,
partagé en écriture:FILE_SHARE_WRITE
ou encore les deux: FILE_SHARE_READ | FILE_SHARE_WRITE

lpSecurityAttributes pour indiquer qu'un processus fils peut ou non hériter du fichier. NULL n'autorisant pas l'héritage.
dwCreationDisposition pour indiquer la méthode à utiliser pour lire ou créer le fichier:

CREATE_NEW: Création du fichier. Si le fichier existe déjà, la fonction retournera une erreur.
CREATE_ALWAYS: Création d'un fichier ou écrasement du fichier si celui-ci existe déjà.
OPEN_EXISTING: Ouverture d'un fichier existant. Si le fichier n'existe pas, le fonction retourne une erreur.
OPEN_ALWAYS Ouverture du fichier. Si le fichier n'existe pas il est créé.

dwFlagsAndAttributes indique les attributs utilisés pour créer le fichier. Si le fichier existe déjà, les nouveaux attributs seront combinés aux anciens.

Attributs Désignations
FILE_ATTRIBUTE_ARCHIVE Ce fichier peut-être archivé
FILE_ATTRIBUTE_ENCRYPTED

Le fichier ou le répertoire est crypté. Sans effet si l'attribut FILE_ATTRIBUTE_SYSTEM est positionné

Si l'attribut est posé sur un répertoire, alors l'attribut est deviendra un atribut par défaut pour tous les nouveaux fichiers ou répertoires.

FILE_ATTRIBUTE_HIDDEN Le fichier est caché.
FILE_ATTRIBUTE_NORMAL Fichier normal, il n'est évidemment pas pris en compte si d'autres attributs sont posés !
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED Le fichier ne peut pas être indexé
FILE_ATTRIBUTE_READONLY Fichier en lecture seul !
FILE_ATTRIBUTE_SYSTEM Fichier système !
FILE_ATTRIBUTE_TEMPORARY Fichier temporaire.

Il exite d'autres attibuts, mais non utiles pour le moment.

En sortie, la fonction retourne un handle sur le fichier ouvert ou INVALID_HANDLE_VALUE en cas d'erreur.

Remarque:Si vous essayez d'accèder à un fichier sur une disquette ou un CD alors qu'il n'y a pas de disquette ou de CD dans le lecteur, le système va
afficher un message vous demandant d'insérer le média correspondant. Pour éviter cela, utiliser la fonction SetErrorMode(SEM_FAILCRITICALERRORS).

 

Lire le contenu d'un fichier

La commande permettant de lire le contenu d'un fichier est ReadFile()

BOOL ReadFile(

HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped

);

Les paramètres étant:

hFile pour le handle du fichier retourné par la fonction CreateFile().
lpBuffer qui va être un pointeur sur un buffer qui va recevoir les données.
nNumberOfBytesToRead qui sera le nombre d'octet à lire.
lpNumberOfBytesRead pointeur sur une variable qui recevra le nombre d'octets lus (Cette variable devra être DWORD). Si la valeur est différente à celle demandée c'est que la fin du fichier est atteinte.
lpOverlapped sera positionné à NULL dans un premier temps.

 

Remarque:Si vous essayez de lire un fichier sur une disquette ou un CD alors qu'il n'y a pas de disquette ou de CD dans le lecteur, le système va
afficher un message vous demandant d'insérer le média correspondant. Pour éviter cela, utiliser la fonction SetErrorMode( SEM_NOOPENFILEERRORBOX).

Image non trouvée ! Si lpOverlapped est NULL, lpNumberOfBytesRead ne devra pas être NULL. De même Si lpNumberOfBytesRead est NULL, lpOverlapped ne devra pas être NULL.

Ecrire dans un fichier

La fonction est similaire à ReadFile(), sauf qu'elle se nomme WriteFile() !!!

BOOL WriteFile(

HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped

);

Pour tout le reste, c'est 100% pareil !

 

Fermer le fichier

BOOL CloseHandle(
HANDLE hObject
);

Se positionner dans le fichier

Pour se positionner dans le fichier à partir du début, de la position courante ou de la fin du fichier:

DWORD SetFilePointer(

HANDLE hFile,
LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh,
DWORD dwMoveMethod

);


Les paramètres étant:

hFile pour le handle du fichier.

lDistanceToMove: partie basse d'un nombre sur 64 bits du déplacement si lpDistanceToMoveHigh n'est pas NULL. Sinon, c'est un nombre signé sur 32 bits.

lpDistanceToMoveHigh: pointeur sur une variable contenant la partie haute d'un nombre sur 64 bits signé correspondant au déplacement. si la valeur passée est NULL, le déplacement sera sur 32 bits.

dwMoveMethod: Origine du déplacement (voir le tableau ci-dessous)

Attributs Description
FILE_BEGIN Déplacement à partir du début du fichier
FILE_CURRENT Déplacement à partir de la position actuelle ou courante du fichier
FILE_END Déplacement à partir de la fin du fichier

En sortie: Si la valeur de lpDistanceToMoveHigh est NULL, la fonction retourne INVALID_SET_FILE_POINTER si problème, sinon se sera la nouvelle position du pointeur.

Si la valeur de lpDistanceToMoveHigh n'est pas NULL, la fonction retourne INVALID_SET_FILE_POINTER si problème, sinon se sera la partie basse de la nouvelle position du pointeur. La variable indiquée dans lpDistanceToMoveHigh recevra la partie haute de la nouvelle position.

Problème:

Il faudra vérifier que l'on ne confond pas INVALID_SET_FILE_POINTER avec un déplacement. Pour cela, il faut impérativement utiliser GetLastError(). Si la valeur retournée est NO_ERROR, c'est que tout est ok.

 

Pour se positionner à la fin d'un fichier:

BOOL SetEndOfFile(
HANDLE hFile
);

Connaîte la taille d'un fichier:

Pour connaître la taille d'un fichier, le plus simple sera d'utiliser la fonction GetFileSize()

DWORD GetFileSize(

HANDLE hFile,
LPDWORD lpFileSizeHigh

);

lpFileSizeHigh pourra être NULL si on ne veut pas avoir la partie haute de la taille.

Là aussi, on peut avoir des problèmes:

Il faudra vérifier que l'on ne confond pas INVALID_SET_FILE_POINTER avec un déplacement. Pour cela, il faut impérativement utiliser GetLastError(). Si la valeur retournée est NO_ERROR, c'est que tout est ok.

Remarque: Cette fonction retourne une taille en DWORD. Il faudra utiliser GetFileSizeEx() pour connaître des tailles plus importantes.