Évidemment, on peut parcourir un fichier en utilisant fgetl ou une fonction similaire et incrémenter un compteur, mais existe-t-il un moyen de déterminer le nombre de lignes dans un fichier sans faire une telle boucle?
J'aime utiliser le code suivant pour exactement cette tâche
fid = fopen('someTextFile.txt', 'rb');
%# Get file size.
fseek(fid, 0, 'eof');
fileSize = ftell(fid);
frewind(fid);
%# Read the whole file.
data = fread(fid, fileSize, 'uint8');
%# Count number of line-feeds and increase by one.
numLines = sum(data == 10) + 1;
fclose(fid);
C'est assez rapide si vous avez assez de mémoire pour lire tout le fichier à la fois. Cela devrait fonctionner pour les fins de ligne de style Windows et Linux.
Edit: J'ai mesuré la performance des réponses fournies jusqu'à présent. Voici le résultat pour déterminer le nombre de lignes d'un fichier texte contenant 1 million de valeurs doubles (une valeur par ligne). Moyenne de 10 essais.
Author Mean time +- standard deviation (s)
------------------------------------------------------
Rody Oldenhuis 0.3189 +- 0.0314
Edric (2) 0.3282 +- 0.0248
Mehrwolf 0.4075 +- 0.0178
Jonas 1.0813 +- 0.0665
Edric (1) 26.8825 +- 0.6790
Ainsi, les approches les plus rapides utilisant Perl et lisant tout le fichier sous forme de données binaires. Je ne serais pas surpris si Perl lisait également en interne de grands blocs du fichier au lieu de le parcourir en boucle ligne par ligne (devinez, ne savez rien de Perl).
L'utilisation d'une boucle fgetl()
- simple est 25 fois plus lente que les autres approches.
Edit 2: Inclut la 2ème approche d'Edric, qui est beaucoup plus rapide et à égalité avec la solution Perl, je dirais.
Je pense qu'une boucle est en fait la meilleure - toutes les autres options suggérées jusqu'à présent reposent soit sur des programmes externes (besoin de vérifier les erreurs; besoin de str2num; plus difficile de déboguer/exécuter multiplate-forme, etc.) ou de lire le fichier entier en une fois. . Les boucles ne sont pas si mauvaises. Voici ma variante
function count = countLines(fname)
fh = fopen(fname, 'rt');
assert(fh ~= -1, 'Could not read: %s', fname);
x = onCleanup(@() fclose(fh));
count = 0;
while ischar(fgetl(fh))
count = count + 1;
end
end
EDIT: Jonas souligne à juste titre que la boucle ci-dessus est vraiment lente. Voici une version plus rapide.
function count = countLines(fname)
fh = fopen(fname, 'rt');
assert(fh ~= -1, 'Could not read: %s', fname);
x = onCleanup(@() fclose(fh));
count = 0;
while ~feof(fh)
count = count + sum( fread( fh, 16384, 'char' ) == char(10) );
end
end
Ce n'est toujours pas aussi rapide que wc -l
, mais ce n'est pas un désastre non plus.
J'ai trouvé un bon tour ici :
if (isunix) %# Linux, mac
[status, result] = system( ['wc -l ', 'your_file'] );
numlines = str2num(result);
elseif (ispc) %# Windows
numlines = str2num( Perl('countlines.pl', 'your_file') );
else
error('...');
end
où 'countlines.pl'
est un script Perl contenant
while (<>) {};
print $.,"\n";
Vous pouvez lire le fichier entier en une fois, puis compter le nombre de lignes que vous avez lues.
fid = fopen('yourFile.ext');
allText = textscan(fid,'%s','delimiter','\n');
numberOfLines = length(allText{1});
fclose(fid)
Je recommanderais d'utiliser un outil externe pour cela. Par exemple, une application appelée cloc
, que vous pouvez télécharger ici gratuitement.
Sur linux, vous tapez simplement cloc <repository path>
et vous obtenez
YourPC$ cloc <directory_path>
87 text files.
81 unique files.
23 files ignored.
http://cloc.sourceforge.net v 1.60 T=0.19 s (311.7 files/s, 51946.9 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
MATLAB 59 1009 1074 4993
HTML 1 0 0 23
-------------------------------------------------------------------------------
SUM: 60 1009 1074 5016
-------------------------------------------------------------------------------
Ils prétendent également que cela devrait fonctionner sur les fenêtres.