在工作中会有很多特殊的需要,比如我现在就遇到一个需要将大型的文本格式数据文件(比如5G)读取到MATLAB中,同时进行一定的处理。由于XP的内存是绝对没有办法将5G的数据一次性加载到工作空间的,此时一般我们是对数据进行分段处理,为了防止长时间等待,让用户以为是死机了,这个时候我们希望添加一个进度条告诉用户处理到什么地方了。但是我们必须先统计文件的行数,才能给出进度。

另外有些用户希望获取文件的长度(字符个数),哦这个其实很简单!

fid=fopen('data.csv');

fseek(fid,0,'eof')

filelength = ftell(fid);

fclose(fid);

现在问题来了,如何获取文本文件的行数呢??下面我们提供几种解决方案吧!本文代码中测试的data.csv数据文件总共有10万行,大概77M。

方法一

最容易想到的就是使用MATLAB的fgetl或fgets函数,对文本按行读取,然后对行数进行累加。

tic

fid=fopen('data.csv'); % 打开文件

row=0;

while ~feof(fid) % 是否读取到文件结尾

[~]=fgets(fid); %

或者fgetl

row=row+1; % 行数累加

end

fclose(fid); % 及时关闭文件是个好习惯

row

toc

运行结果如下,fgets大概耗时大概10s,如果fgetl速度会慢一些,大概需要13s,可能是因为fgel需要将尾部的回车去掉而增加了操作吧

row =

100000

Elapsed time is 10.556020 seconds.

方法二

其实MATLAB处理复杂文本文件,灵活性最好和效率最高的是textscan函数。灵活性就不用说了,textscan提供很多定制功能,比如跳过的标题行数、设置空白字符等经过测试;至于效率,经过测试,textscan在处理某些数据下是效率fscanf的10倍以上,另外仔细看看dlmread函数,其实也是调用了textscan函数。

接着有人要问,textscan是用来读取数据的,怎么用来统计行数?其实我们只是占了一个便宜而已!因为textscan提供了一个忽略特定字符串的功能。

tic

fid=fopen('data.csv');

% '%*[^n]' 这个设置估计有人看不懂,特别是后面的那个%

% ,表示读取一个字符

%

%*[^n],*表示忽略,[^]表示不是[]字符,合起来的意思就是忽略所有不是n(回车)的字符,更直接的意思就是忽略到行尾

data = (textscan(fid,'%*[^n]'));

fclose(fid);

row=length(data{1})

toc

row =

100000

Elapsed time is 12.660186 seconds.

运行时间12s,好像有点长哦,没有想象中的那么厉害。另外这个方法有两个个致命的弱点,因为程序必须每行读取一个字符

(1)假如文件很大,比如10G,那么就算每行读取一个字符,这个也超出了XP内存,因此读取失败!

(2)假如存在空行,那么会将回车读入,%*[^n]于是就自动忽略了下一行,因此统计的行数不准确!

从上面分析textscan并不适合用于统计大型文件的行数,但是这并不能否定textscan的效率,因为textscan是千真万确一行一行的处理和读取数据文件,只是我们读取第一个字符然后忽略了剩下的所有字符而已。

方法三

其实越是底层的函数效率是越高的,只是使用不方便而已。MATLAB还有一个fread函数,不过这是默认处理的是二进制文件,不过没有关系,文本文件只是一个编码而已,我们还是可以使用fread进行读取的。

tic

fid=fopen('data.csv','rt'); % t是告诉fread是这里文本文件

row=0;

while ~feof(fid)

%

一次性读取10000字符,计算其中的回车个数,其中10是回车的ASCII编码

%

'*char'表示每次读取一个字符,*表示输出也是字符

%

放心fread现在已经可以自动识别中文了,万一还是识别不了,

% 请在fopen中指定文件编码格式,比如gbk

row=row+sum(fread(fid,10000,'*char')==char(10));

%

下面还有一个类似的方法,但是效率低很多,大概是上面的一半

%

'char'表示每次读取一个字符,但是默认输出double,

%

也就是说读取char然后转换double中间有转换能快吗?

%

row=row+sum(fread(fid,10000,'char')==10);

end

fclose(fid);

row

toc

这个效率呱呱的,简直天壤之别呀,才1.7s!看来这个结果比较令我满意哦!

row =

100000

Elapsed time is 1.721880 seconds.

方法四

上面的方法都是在循环中不停地对文件进行访问,自然效率是高不起来的。对于大型文件,还有其他什么好的解决方案呢,也许这个时候需要借组外部力量了!传说perl语言对文件操作有很多优势,同时linux提供了wc命令对文件进行行统计,不妨试试?

tic

% 判断计算机操作系统

if (isunix) % Linux系统提供了wc命令可以直接使用

% 使用syetem函数可以执行操作系统的函数

% 比如window中dir,linux中ls等

[~, numstr] = system( ['wc -l

', 'data.csv'] );

row=str2double(numstr);

elseif (ispc) % Windows系统可以使用perl命令

if

exist('countlines.pl','file')~=2

%

perl文件内容很简单就两行

% while

(<>) {};

% print

$.,"n";

fid=fopen('countlines.pl','w');

fprintf(fid,'%sn%s','while

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

fclose(fid);

end

% 执行perl脚本

row=str2double(

perl('countlines.pl', 'data.csv') );

end

row

toc

楼主使用的是window系统,调用perl,果然不负众望,才0.89秒

row =

100000

Elapsed time is 0.889994 seconds.

其实上面的方法在处理真正的大型文件时,还是可能不是很理想的,本文中测试的文件才77M算不上什么大型文件,后来对一个大约80万行,大小622M的csv文件进行测试,使用perl方法结果如下:

row =

800001

Elapsed time is 15.859564 seconds.

文件越大,计算时间不是简单的线性增加!到了真正几十甚至几百G这样的大型数据,上面的方法几乎是不能忍受的,也许还有更好的解决方法吧!

有人问有什么好的方法生成上面的测试数据呀?我在MATLAB中是这样生成的!

data=rand(10000,100); % 随机生成1w行数据

save data.csv data -ascii % 保存为文本

for ii=1:5 % 自己复制5次,生成2^5=32万行

% 这里使用了dos命令,效率会好些

% 千万不要使用fprint,否你会残废的

!type data.csv >>

data.csv

end

matlab中读文件的行数_[转载]MATLAB中获取大型文本文件行数方法研究(转)相关推荐

  1. git中.ssh文件夹在哪_关于git中的https和ssh,权限等问题

    本地仓库和远程仓库通讯的两种方式:https和ssh 1.使用https通信: 公有仓库,用户B具有仓库A的克隆(只读)权限,没有push(修改)等权限:克隆时,用户B要输入自己的用户和密码进行身份识 ...

  2. java内存中读文件_关于内存管理:读取Java中的大文件

    我需要一个非常了解Java和内存问题的人的建议. 我有一个大文件(大约1.5GB),我需要将此文件切成许多小文件(例如100个小文件). 我通常知道如何做到这一点(使用BufferedReader), ...

  3. Python中读文件、写文件的操作方法

    ▶ Python中读文件操作方法 在Python编程中,从一个文件中读取数据可以通过以下3种方式. 1.使用read方法读取文件 read方法可以从文件中读取数据,该方法的定义语法如下: read(s ...

  4. matlab中读文件的行数_【Matlab】 读取文件各种方法

    本技术支持指南主要处理:ASCII, binary, and MAT files.要得到MATLAB中可用来读写各种文件格式的完全函数列表,可以键入以下命令: help iofun MATLAB中有两 ...

  5. excel 多行插入_在Excel中插入多行

    excel 多行插入 If you've used Excel for a while, you have lots of skills that you might assume everyone ...

  6. C++中读文件以及getline和atof函数的运用

    文章目录 读文件 getline函数 atof函数 读文件 一次性从某个文件中读取数据,并存入固定的vetor结构体中. 文件中的数据结构为: A,B,C,D A,B,C,D A,B,C,D A,B, ...

  7. mysql mysql_row 整行数据_有关mysql中ROW_COUNT()的小例子

    mysql中的ROW_COUNT()可以返回前一个SQL进行UPDATE,DELETE,INSERT操作所影响的行数 注:mysql中的ROW_COUNT()可以返回前一个SQL进行UPDATE,DE ...

  8. nodejs命令行执行程序_在NodeJS中编写命令行应用程序

    nodejs命令行执行程序 by Peter Benjamin 彼得·本杰明(Peter Benjamin) 在NodeJS中编写命令行应用程序 (Writing Command-Line Appli ...

  9. python中读取文件编码_[转载]python中使用文件的读取编码问题

    原文链接:https://www.cnblogs.com/qianboping/p/6524420.html 今天想写个程序合并文件的,以前一直觉得python的编码解码好烦,只要处理文件合并之类的都 ...

最新文章

  1. 惠普鼠标g260_惠普g260鼠标怎么样 惠普鼠标怎么样?
  2. Quartz 实现分布式任务调度
  3. 【pmcaff】一个PM的十年分享:如果的事
  4. 工控机的io开发_Amazing!从树莓派4B主板到嵌入式无风扇工控机,只需三步!
  5. 高级指引——手动创建节点分组 Group
  6. linux系统盘比较小,35M的中文linux硬盘简单安装方法Live-CD:SliTaz.tw-全世界最小的li...
  7. iOS之 开发常用到的宏定义
  8. 飞鸽传书CSDN的搜索结果
  9. 解决透视变换后图片信息丢失的问题
  10. 增加或修改的存储过程
  11. c语言游戏计算器代码,C语言计算器代码.doc
  12. 企业微信小程序(企业内部)怎么自定义工作台和通过中文名模糊查询到员工的个人信息和userid
  13. ITIL学习笔记——核心流程之:服务级别管理
  14. Mysql支持translate函数吗_oracle 中的translate函数
  15. 前端网站连接MySQL数据库
  16. 第16期高级转录组分析和R数据可视化培训(2022年1月)
  17. RDS Mysql Single-AZ和Multi-AZ性能差异
  18. October——I Will Talk
  19. 直流无刷电机的调试与代码开源(配套资源)
  20. autojs教程:一起来养猪app脚本代码

热门文章

  1. 脑细胞膜等效神经网路简单分类实例
  2. PyTorch 实现孪生网络识别面部相似度
  3. selenium多个窗口
  4. 苹果「热修复门」事件复盘、分析和展望
  5. ONVIF测试方法及工具
  6. java 使用正则表达式过滤HTML中标签
  7. shell 下的运算表达
  8. 使用XML模板在excel进行配置
  9. 关于Java中的迭代器
  10. JMX操作ActiveMQ(2)