显然,可以使用 fgetl 或类似函数遍历文件并增加一个计数器,但是有没有一种方法可以确定文件中的行数而不进行这样的循环?
5 回答
我喜欢使用下面的代码来完成这个任务
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);
如果您有足够的内存一次读取整个文件,则速度非常快。它应该适用于 Windows 和 Linux 风格的行尾。
编辑:我测量了迄今为止提供的答案的表现。这是确定包含 100 万个双精度值(每行一个值)的文本文件的行数的结果。平均 10 次尝试。
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
使用 Perl 并将所有文件作为二进制数据读取的方法是如此之快。如果 Perl 在内部同时读取文件的大块而不是逐行循环,我不会感到惊讶(只是猜测,对 Perl 一无所知)。
使用简单的fgetl()
-loop 比其他方法慢 25-75 倍。
编辑 2:包括 Edric 的第二种方法,我会说,它比Perl 解决方案更快且相当。
我认为循环实际上是最好的——到目前为止,所有其他选项都建议要么依赖外部程序(需要错误检查;需要 str2num;更难调试/跨平台运行等),要么一次性读取整个文件. 循环并不是那么糟糕。这是我的变种
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
编辑:乔纳斯正确地指出,上面的循环真的很慢。这是一个更快的版本。
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
它仍然没有那么快wc -l
,但也不是灾难。
我在这里找到了一个不错的技巧:
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
perl 脚本在哪里'countlines.pl'
,包含
while (<>) {};
print $.,"\n";
您可以一次读取整个文件,然后计算您已阅读的行数。
fid = fopen('yourFile.ext');
allText = textscan(fid,'%s','delimiter','\n');
numberOfLines = length(allText{1});
fclose(fid)
我建议为此使用外部工具。例如一个名为 的应用程序cloc
,您可以在这里免费下载。
在 linux 上,您只需键入cloc <repository path>
并获取
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
-------------------------------------------------------------------------------
他们还声称它应该在 Windows 上工作。