Fichiers et répertoires dans Squeak
From OFSET Wiki
Contents |
[edit] Tester l'existence d'un fichier
Avec FileStream class>>isAFileNamed:, l'argument est un String qui peut être un chemin relatif ou absolu. Dans le cas d'un chemin relatif, le répertoire courant est pris comme base.
FileStream isAFileNamed: '/etc/fstab'
retourne true sur un systeme unix
FileStream isAFileNamed: 'squeak.image'
retourne true si le fichier squeak.image existe dans le répertoire courant.
FileStream isAFileNamed: 'package-cache/ECompletion-bar.76.mcz'
retourne true si le fichier ECompletion-bar.76.mcz existe dans le sous-répertoire package-cache du répertoire courant.
[edit] Créer et écrire dans un fichier
[edit] Créer est écrire
Avec FileStream>>fileNamed:, on récupère un Stream (une instance d'une des sous-classes de Stream) dans lequel on peut écrire; on ferme le Stream pour assurer l'écriture physique. Si le fichier n'existe pas au préalable, alors il est créé vide.
| st | st := FileStream fileNamed: 'trux.txt'. st nextPutAll: 'xxxxxxxxxxxxxxxxxxxx'; st close. st := FileStream fileNamed: 'trux.txt'. st nextPutAll: '---'; st close.
En résultat, le fichier trux.txt contient '---xxxxxxxxxxxxxxxxx'
Si on veut que le contenu du fichier soit '---', alors il faut utiliser FileStream class>>forceNewFileNamed: qui, si le fichier existe, le supprime et le re-crée (c'est bien sur beaucoup plus couteux) :
| st | st := FileStream forceNewFileNamed: 'trux.txt'. st nextPutAll: 'xxxxxxxxxxxxxxxxxxxx'; st close. st := FileStream forceNewFileNamed: 'trux.txt'. st nextPutAll: '---'; st close.
[edit] Gérer les erreurs
L'inconvénient est que si le fichier ne peut pas être créé, alors, un dialogue standard surgit. Essayez par exemple avec :
FileStream forceNewFileNamed: '/trux.txt'
Un utilisateur non root ne peut pas créer /trux.txt.
Si on veut éviter le dialogue et gérer differemment le problème, il faut intercepter une exception de la façon suivante :
[FileStream forceNewFileNamed: '/trux.txt'] on: FileStreamException do: [:ex | ex explore]
Ici, si le fichier ne peut pas être créé, alors, l'exception est explorée avec ex explore. Bien sur, on peut faire autre chose (gérer l'erreur) à la place de ex explore.
Si on ne peut pas écrire dans le fichier FileStream class >>fileNamed: retourne nil. Il faut donc tester le retour :
| st |
(st := FileStream fileNamed: 'trux.txt')
ifNotNil: [st nextPutAll: 'xxxxxxxxxxxxxxxxxxxx'. st close].
En règle générale, il vaut mieux assurer que le fichier est bien fermé quoiqu'il arrive. Pour cela on peut utiliser BlockClosure>>ensure:.
Avec FileStream class >>fileNamed: :
| st |
(st := FileStream fileNamed: 'trux.txt')
ifNotNil: [[st nextPutAll: 'xxxxxxxxxxxxxxxxxxxx'] ensure: [st close]].
Bien sur, ici, l'intérêt de ensure: est nul. C'est utile dans le cas suivant :
| st |
(st := FileStream fileNamed: 'trux.txt')
ifNotNil: [[unObjet ecrireDansFlot: st] ensure: [st close]].
En effet, ecrireDansFlot: peut provoquer une exception (on ne sait pas), ensure: garanti quand même la fermeture du flôt.
Et avec FileStream class>>forceNewFileNamed: en évitant le dialogue standard :
[[st := FileStream forceNewFileNamed: '/trux.txt']
on: FileStreamException do: [:ex | "code si ko"]. "ici code si ok" ]
ensure: [st ifNotNil: [st close]]
[edit] Suppression de fichier
FileDirectory deleteFilePath: '/home/machin/trux.txt'
Attention, l'argument est le chemin absolu du fichier.
On peut récupérer un chemin absolu à partir d'un chemin relatif de la façon suivante :
FileDirectory default fullNameFor: 'momo/platypus_tmp.step'
[edit] Récupérer le contenu d'un fichier
[edit] Lire un fichier
On peut simplement ouvrir un stream en lecture et récuperer son contenu :
| contenu st | st := FileStream readOnlyFileNamed: 'trux.txt'. contenu := st contents. st close
On peut aussi ouvrir un stream en lecture/écriture et récupérer son contenu :
| contenu st | st := FileStream fileNamed: 'trux.txt'. contenu := st contents. st close
[edit] Gérer les erreurs
Le fichier peut ne pas exister ou bien ne pas être lisible. Voici une méthode qui retourne le contenu d'un fichier, un String vide est retourné en cas d'erreur :
fileContentsOf: filename | fileStream result | [fileStream := StandardFileStream readOnlyFileNamed: filename] on: FileStreamException do: [^ '']. result := fileStream contents. fileStream close. ^ result
[edit] Créer un répertoire
[edit] Pour un sous-répertoire
On crée un FileDirectory avec le chemin du répertoire père du nouveau répertoire puis on lui demande de créer un sous-répertoire :
(FileDirectory on: '/home/plantec/dvpt/MUIDoc' ) createDirectory: 'AAA'
[edit] Assurer la création de tout un chemin
(FileDirectory on: '/home/plantec/dvpt/MUIDoc/AAAA/BBBBB/CCCC' ) assureExistence
[edit] Récupérer la liste des fichiers d'un répertoire
aDirectory := FileDirectory on: '/home/cpulo/data'. aDirectory fileNames.
[edit] Construire un chemin indépendamment du système hôte
Il faut faire attention au séparateur de chemin :
- "/" sous unix
- "\" sous dos/windows
- ":" sous mac
On récupère la sous-classe de FileDirectory correspondant au système en cours avec FileDirectory class>>activeDirectoryClass et on récupère le séparateur avec FileDirectory activeDirectoryClass slash.
sep := FileDirectory activeDirectoryClass slash. path := sep, 'home', sep, 'cpulo', sep, 'data'. aDirectory := FileDirectory activeDirectoryClass on: path. aDirectory fileNames.

