FAQ MATLAB
FAQ MATLABConsultez toutes les FAQ
Nombre d'auteurs : 11, nombre de questions : 172, dernière mise à jour : 29 septembre 2022
- Quelles sont les fonctions de lecture et écriture ?
- Pourquoi doit-on appeler la fonction fclose après avoir ouvert un ficher avec fopen ?
- Quels sont les formats de fichier supportés par MATLAB ?
- Comment tester l'existence d'un fichier ou d'un dossier ?
- Comment concaténer le nom d'un fichier et celui d'un répertoire ?
- Comment lister les fichiers d'une certaine extension dans un répertoire ?
- Comment nommer une suite de fichiers : nom_1.ext, nom_2.ext... nom_N.ext ?
- Comment passer l'entête d'un fichier texte en lecture ?
- Séparateur décimal : point ou virgule ?
-
Les fonctions avec fopenDocumentation de la fonction fopen / fcloseDocumentation de la fonction fclose.
La fonction fopen permet l'ouverture du fichier, les différentes permissions autoriseront soit la lecture, soit l'écriture, soit les deux.Sélectionnezfid = fopen(monFichier, <permission>);
Dès lors que cette fonction est utilisée, il faudra obligatoirement fermer le fichier une fois les opérations effectuées dessus terminées, et ceci avec la fonction fclose :
Sélectionnezfclose(fid);
Il se peut que suite à une erreur, on perde cet identifiant et que l'on ne puisse plus faire cette opération. Dans ce cas, on exécutera la ligne :
Sélectionnezfclose(
'all'
)
Le fichier ouvert, on utilisera pour l'écriture :-
fprintfDocumentation de la fonction fprintf : écriture de texte formaté
Sélectionnezx = 0:.1:10; fprintf(fid,
' x y\n'
); fprintf(fid,'%5.2f %10.4f\n'
, [x ; exp(x)]); -
fwriteDocumentation de la fonction fwrite : écriture sous forme binaire
Sélectionnezfwrite(fid,
'MATLAB'
,'uint8'
)
Pour la lecture :-
fscanfDocumentation de la fonction fscanf : lecture sous forme formatée
SélectionnezT = fscanf(fid,
'%f %f\n'
, [2 Inf]) -
textscanDocumentation de la fonction textscan : lecture sous forme formatée, avec de nombreuses options telles que
'HeaderLines'
permettant de sauter des lignes d'entête,'Delimiter'
spécifiant le séparateur entre les différentes données… Lorsque la lecture devient fastidieuse, c'est souvent LA fonction à utiliserSélectionnezT = textscan(fid,
'%5.2f %10.4f'
,'HeaderLines'
, 1) -
freadDocumentation de la fonction fread : lecture sous forme binaire
SélectionnezT = fread(fid,
'uint8=>char'
).'; -
fgetlDocumentation de la fonction fgetl, fgetsDocumentation de la fonction fgets : lecture d'une ligne en gardant ou non le caractère de fin de ligne
Sélectionnezligne = fgetl(fid);
% caractère(s) de fin de ligne non gardé(s)
ligne = fgets(fid);% caractère(s) de fin de ligne gardé(s)
Pour se déplacer dans le fichier :-
ftellDocumentation de la fonction ftell : obtenir la position actuelle
Sélectionnezposition = ftell(fid);
-
fseekDocumentation de la fonction fseek : se positionner par rapport au début, à la fin ou la position actuelle du fichier
Sélectionnezfseek(fid, offset, origine);
-
frewindDocumentation de la fonction frewind : revenir au début du fichier
Sélectionnezfrewind(fid);
-
feofDocumentation de la fonction feof : vérifier si la fin du fichier est atteinte
Sélectionnezfin_atteinte = feof(fid);
Si une erreur s'est produite lors de la lecture ou de l'écriture, la fonction ferrorDocumentation de la fonction ferror servira à récupérer le message d'erreur et son numéro :
Sélectionnez[message, errnum] = ferror(fid);
Remarque : suivant le système d'exploitation dans lequel a été/sera écrit le fichier, on pourra trouver les caractères de fin de ligne suivants :
- Windows : \r\n soit [13 10] ;
- Unix/Linux ou Mac OS X (et +) : \n soit 10 ;
- Mac (jusqu'à la version 9) : \r soit 13 ;
-
-
Les fonctions dlmreadDocumentation de la fonction dlmread / dlmwriteDocumentation de la fonction dlmwrite : tableaux 1D ou 2D numériques
Outre les fonctions avec fopen/fclose, la lecture et l'écriture de matrices numériques peuvent se faire facilement à l'aide des fonctions dlmread/dlmwrite, en utilisant le délimiteur selon le besoin :
Sélectionnezdlmwrite(monFichier, maMatrice, <delimiteur>) maMatrice = dlmread(monFichier, <delimiteur>)
-
Les fonctions saveDocumentation de la fonction save / loadDocumentation de la fonction load : pour les fichiers .mat
Afin de sauvegarder rapidement un workspace, des variables de type structure, tableaux de cellules, ou n'importe quelle autre, la fonction save est toute indiquée.
Sélectionnezsave(monfichier)
% Sauvegarde toutes les variables du workspace courant
save(monfichier,'X'
,'Y'
)% Sauvegarde seulement les variables X et Y
load(monfichier)% Charge toutes les variables contenues dans le fichier
load(monfichier,'X'
,'Y'
)% Ne charge que X et Y
S = load(monfichier);% Retourne toutes les variables contenues dans la structure S.
Remarque : la fonction load peut aussi servir à charger des fichiers contenant des matrices de données numériques (pouvant être sauvées avec save avec l'option
'-ASCII'
). -
Les fonctions importdataDocumentation de la fonction importdata / uiimportDocumentation de la fonction uiimport : multiple-usage
La fonction importdata (ou uiimport de façon manuelle) peut aussi accéder facilement au contenu d'un grand nombre de types de fichiers.
Pour plus de renseignements sur les différentes extensions et leurs fonctions associées : Quels sont les formats de fichier supportés par MATLAB ?.
Vous avez au moins deux raisons de toujours utiliser fcloseDocumentation de la fonction fclose après avoir ouvert un ficher avec fopenDocumentation de la fonction fopen.
-
La première raison est qu'il existe une limite du nombre de fichiers ouverts simultanément par fopen :
Sélectionnezif
exist('fopentest'
,'dir'
)~=7 mkdir('fopentest'
);else
delete('./fopentest/data*.bin'
);end
for
n = 1:5000 filename = fullfile('./fopentest'
, sprintf('data%d.bin'
, n)); fid(n) = fopen(filename,'w'
);if
fid(n)==-1break
end
end
disp(n) fclose('all'
);Avec MATLAB R2011b sur Windows 7 :
Nombre maximal de fichiers ouverts simultanément : 509La même chose sur Linux :
Nombre maximal de fichiers ouverts simultanément : 3813Donc si vous exécutez votre code plusieurs fois et/ou avez besoin de générer d'avantage de fichiers dans votre code, vous ne pourrez tout simplement pas si vous ne fermez pas les précédents avec fclose.
Note : il y a en fait deux limites, une imposée par le système d'exploitation, l'autre par une constante du code C qui sert de base à fopen.
-
La deuxième raison pour laquelle il faut toujours utiliser fclose est que le système d'exploitation bloque certains accès aux fichiers ouverts avec fopen entre différents processus.
Un exemple simple, tapez ceci :
Sélectionnezfid = fopen(
'data.bin'
,'w'
);Puis, essayez de supprimer le fichier depuis l'explorateur de votre système d'exploitation.
Windows 7 renvoie :
Cette action ne peut pas être réalisée car le fichier est ouvert dans MATLAB.
Fermez le fichier et réessayez.Maintenant fermez le fichier dans MATLAB :
Sélectionnezfclose(fid);
Vous pouvez maintenant supprimer le fichier depuis une application externe à MATLAB.
Vous traitez peut-être moins de fichiers sans atteindre cette limite, et n'y accédez pas en dehors de MATLAB…
Peu importe, c'est toujours une bonne habitude à prendre. Et rien ne dit que ce sera le cas dans un futur projet.
La liste des formats de fichier supportés nativement par MATLAB est donnée sur la page de la documentation de la fonction fileformats :
doc fileformats
Pour la dernière version de MATLAB : Supported File Formats for Import and Export.
Une recherche dans le File Exchange peut permettre de trouver d'autres fonctions de lecture/écriture de fichier.
Tester l'existence d'un fichier est une action courante qu'il est nécessaire de mettre en œuvre pour améliorer la robustesse de son code.
MATLAB est livré avec une fonction nommée exist qui effectue ce test.
La documentation de existDocumentation de la fonction exist indique que cette fonction renvoie une valeur en fonction de la nature de l'objet dont on souhaite tester l'existence. Dans notre cas, les valeurs renvoyées pour l'existence d'un fichier ou d'un dossier sont respectivement 2 et 7.
Donc pour tester l'existence d'un fichier, on fera par exemple :
if
exist(filename, 'file'
)~=2
error('Le fichier n''existe pas'
);
end
Et pour tester l'existence d'un dossier, on fera par exemple :
if
exist(pathname, 'file'
)~=7
error('Le dossier n''existe pas'
);
end
Pour obtenir le chemin d'accès complet à un fichier, il faut concaténer le nom du fichier avec celui du dossier où il se trouve.
On voit souvent ce type de concaténation :
repertoire = 'D:\dossierA\dossierB\'
;
fichier = 'image.jpg'
;
chemin = [repertoire fichier]
ou
repertoire = 'D:\dossierA\dossierB'
;
fichier = 'image.jpg'
;
chemin = [repertoire '\'
fichier]
On voit déjà que la présence ou non du dernier séparateur dans le nom du dossier peut poser problème…
Il y a aussi un autre problème plus grave. Le séparateur de nom n'est pas le même sur tous les systèmes d'exploitation :
OS | Séparateur | Exemple |
---|---|---|
Windows | \ | D:\dossierA\dossierB |
Linux | / | D/dossierA/dossierB |
Si le code doit pouvoir fonctionner sur n'importe quelle machine, il faut pouvoir gérer cette différence. Il est possible de récupérer le séparateur en utilisant la fonction filesepDocumentation de la fonction filesep.
Mais la meilleure solution consiste à utiliser la fonction fullfileDocumentation de la fonction fullfile qui va déterminer automatiquement le séparateur à utiliser en fonction du système d'exploitation courant.
Sous Windows :
>> repertoire = 'D:\dossierA\dossierB'
;
>> fichier = 'image.jpg'
;
>> chemin = fullfile(repertoire, fichier)
chemin =
D:\dossierA\dossierB\image.jpg
ou
>> repertoire = 'D:\dossierA\dossierB\'
;
>> fichier = 'image.jpg'
;
>> chemin = fullfile(repertoire, fichier)
chemin =
D:\dossierA\dossierB\image.jpg
De même sous Linux :
>> repertoire = '/D/dossierA/dossierB'
;
>> fichier = 'image.jpg'
;
>> chemin = fullfile(repertoire, fichier)
chemin =
/D/dossierA/dossierB/image.jpg
ou
>> repertoire = '/D/dossierA/dossierB/'
;
>> fichier = 'image.jpg'
;
>> chemin = fullfile(repertoire, fichier)
chemin =
/D/dossierA/dossierB/image.jpg
Cette technique est très efficace pour concaténer les deux arguments de sortie des fonctions uigetfileDocumentation de la fonction uigetfile et uiputfileDocumentation de la fonction uiputfile :
[fichier, repertoire] = uigetfile;
chemin = fullfile(repertoire, fichier);
Il faut utiliser la fonction dirDocumentation de la fonction dir.
Exemple, pour lister tous les fichiers avec l'extension jpg dans le répertoire C:\monRep :
rep = 'C:\monRep'
;
ext = '*.jpg'
;
chemin = fullfile(rep,ext);
list = dir(chemin);
La fonction dir retourne alors une variable list de type Structure dont les différents champs sont :
- name : nom du fichier ;
- date : date de modification du fichier ;
- bytes : taille du fichier (en octets) ;
- isdir : valeur booléenne 0 (car on ne liste que des fichiers ici) ;
- datenum : date de modification du fichier (format de date MATLAB).
Les fichiers peuvent alors être traités par exemple dans le cas d'image jpeg comme ceci :
rep = 'C:\monRep'
;
ext = '*.jpg'
;
chemin = fullfile(rep,ext);
list = dir(chemin);
for
n = 1:numel(list)
img = imread(fullfile(rep, list(n).name), ext(3:end));
end
Une autre solution consiste à utiliser la fonction lsDocumentation de la fonction ls. Mais le résultat renvoyé par cette fonction dépend du système d'exploitation sur lequel elle est exécutée. Son utilisation est donc moins flexible que celle de la fonction dir.
Il existe deux solutions peu différentes : l'une utilise la fonction sprintfDocumentation de la fonction sprintf, l'autre la concaténation de chaînes de caractères et la fonction num2strDocumentation de la fonction num2str.
Par exemple, pour générer des noms de fichiers test1.txt, test2.txt…, testN.txt :
for
n = 1:3
nomFichier = sprintf('test%d.txt'
,n)
end
ou
for
n = 1:3
nomFichier = ['test'
num2str(n) '.txt'
]
end
Note : comme la fonction num2str fait appel à sprintf, il est généralement plus flexible d'utiliser la solution avec sprintf seul.
Note : si l'on souhaite des noms de fichiers avec un nombre de digits constants, par exemple : test01.txt, test02.txt…, test10.txt :
for
n = 1:10
nomFichier = sprintf('test%02d.txt'
, n)
end
ou
for
n = 1:10
nomFichier = ['test'
num2str(n, '%02d'
) '.txt'
]
end
Remarque : les solutions données ici supposent que le nombre de lignes à passer est connu.
Avec les fonctions de lecture de bas niveau :
% Ouverture du fichier en lecture txt
fid = fopen('data.txt'
,'rt'
);
% Nombre de ligne à passer
N = ...
for
n = 1:N
fgetl(fid);
end
% Continuer la lecture des données utiles ici
% Fermeture du fichier
fclose(fid);
Avec les fonctions de haut niveau textreadDocumentation de la fonction textread et textscanDocumentation de la fonction textscan, il suffit de renseigner la propriété 'HeaderLines'
comme ceci :
textread('data.txt'
, <format>, 'HeaderLines'
, <nombre de lignes à passer>)
ou
fid = fopen('data.txt'
);
textscan(fid, <format>, 'HeaderLines'
, <nombre de lignes à passer>)
fclose(fid);
Il est également possible d'utiliser la fonction dlmreadDocumentation de la fonction dlmread comme ceci :
dlmread('data.txt'
, <délimiteur>, <nombre de lignes à passer>, 0)
Le séparateur décimal communément utilisé dans les pays francophones est la virgule, tandis que dans les pays anglophones, c'est le point qui est majoritairement employé. MATLAB ne tient pas compte des réglages des paramètres locaux de l'ordinateur et utilise toujours le point comme séparateur décimal. La virgule est principalement utilisée pour séparer les valeurs sur une ligne d'un tableau.
Il y aura donc un problème lors de la lecture d'un fichier texte contenant des valeurs numériques avec la virgule comme séparateur décimal.
Par exemple, soit un fichier test.txt contenant les quatre valeurs numériques suivantes :
6,5 1,2
7,2 2,3
La fonction dlmreadDocumentation de la fonction dlmread échouera à la lecture du fichier :
>> M = dlmread('test.txt'
)
M =
6 5 1
2 0 0
voire :
>> M = dlmread('test.txt'
, ' '
)
??? Error using dlmread (line 141)
Mismatch between file and format string.
Trouble reading number from file (row 1u, field 2u) ==> ,5 1,2\n
Pour obtenir une lecture correcte, il faudra donc toujours essayer de générer des fichiers textes avec le point comme séparateur décimal.
Si vous n'avez pas le contrôle sur la création des fichiers, il faudra impérativement en modifier le contenu avant la lecture. Vous pouvez utiliser n'importe quel éditeur de texte pour remplacer les virgules par des points. Vous pouvez également le faire directement avec MATLAB en téléchargeant, par exemple, la contribution repinfileRemplacement de caractères ou de mots dans un fichier texte disponible gratuitement.