有没有在Matlab的方式来确定在一个文件中的行数不通过每一行循环?(Is there a way

2019-06-27 12:44发布

显然,人们可以通过使用fgetl或类似的功能,并增加一个计数器文件循环,但有一种方法来确定线路的一个文件中的数字,没有做这样的循环?

Answer 1:

我喜欢用下面的代码正是这种任务

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样式行尾。

编辑:我测到目前为止提供的答案的性能。 下面是用于确定含有百万双精度值(每行一个值)的文本文件的行数的结果。 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:包括埃德里克的第2个方法,这是更快 ,在标准杆与Perl的解决方案,我会说。



Answer 2:

我认为一个循环,其实是最好的 - 所有其他选项到目前为止建议要么依靠外部程序(需要错误检查;需要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 ,但无论是不是一场灾难。



Answer 3:

我发现了一个很不错的技巧在这里 :

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

其中'countlines.pl'是一个perl脚本,含

while (<>) {};
print $.,"\n";


Answer 4:

您可以一次读取整个文件,然后算你有多少行读取。

fid = fopen('yourFile.ext');

allText = textscan(fid,'%s','delimiter','\n');

numberOfLines = length(allText{1});

fclose(fid)


Answer 5:

我会建议使用该外部工具。 例如一个应用程序称为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上。



文章来源: Is there a way in Matlab to determine the number of lines in a file without looping through each line?