您好,欢迎来到尔游网。
搜索
您的当前位置:首页Matlab?直接读取二进制文件

Matlab?直接读取二进制文件

来源:尔游网


Matlab 直接读取二进制文件

本文作者原创。

matlab可以直接读取二进制数据文件,并且可以将其加入到矩阵中。以充分利用matlab快速处理矩阵的优势。

matlab读取二进制文件,涉及到的函数包括

fopen,fclose,ftell,fseek,fread,fwrite,feof

一、文件打开和关闭

1、打开文件

在读写文件之前,必须先用fopen函数打开或创建文件,并指定对该文件进行的操作方式

fopen函数

调用格式:fid=fopen(文件名,‘打开方式’)

说明:其中fid用于存储文件句柄值,如果返回的句柄值大于0,则说明文件打开成功。文件名用字符串形式,表示待打开的数据文件。常见的打开方式如下:

‘r’:只读方式打开文件(默认的方式),该文件必须已存在。

‘r+’:读写方式打开文件,打开后先读后写。该文件必须已存在。

‘w’:打开后写入数据。该文件已存在则更新;不存在则创建。

‘w+’:读写方式打开文件。先读后写。该文件已存在则更新;不存在则创建。

‘a’:在打开的文件末端添加数据。文件不存在则创建。

‘a+’:打开文件后,先读入数据再添加数据。文件不存在则创建。

另外,在这些字符串后添加一个“t”,如‘rt’或‘wt+’,则将该文件以文本方式打开;如果添加的是“b”,则以二进制格式打开,这也是fopen函数默认的打开方式。

2、关闭文件

文件在进行完读、写等操作后,应及时关闭,以免数据丢失。

fclose函数,

调用格式为:sta=fclose(fid)

说明:该函数关闭fid所表示的文件。sta表示关闭文件操作的返回代码,若关闭成功,返回0,否则返回-1。如果要关闭所有已打开的文件用fclose(‘all’)。

二、二进制文件的读写操作

1、写二进制文件

fwrite函数

按照指定的数据精度将矩阵中的元素写入到文件中。其调用格式为:

COUNT=fwrite(fid,A,precision)

说明:其中COUNT返回所写的数据元素个数(可缺省),fid为文件句柄,A用来存放写入文件的数据,precision代表数据精度,常用的数据精度有:char、uchar、int、long、float、double等。缺省数据精度为uchar,即无符号字符格式。

2、读二进制文件

fread函数可以读取二进制文件的数据,并将数据存入矩阵。其调用格式为:

[A,COUNT]=fread(fid,size,precision)

说明:其中A是用于存放读取数据的矩阵、COUNT是返回所读取的数据元素个数、fid为文件句柄、size为可选项,若不选用则读取整个文件内容;若选用则它的值可以是下列值:N(读取N个元素到一个列向量)、inf(读取整个文件)、[M,N](读数据到M×N的矩阵中,数据按列存放)。precision用于控制所写数据的精度,其形式与fwrite函数相同。

三、应用matlab表功能直接读取通达信K线文件文件

通达信专业版以上会有后台数据到处功能,通过txt文件的方式供其它软件使用。但这里采用的是利用matlab强大的文件功能直接读取通达信的后台数据文件。

通达信后台数据文件K部分主要存放在vipdoc文件夹里,子目录分别存放在sh(上交所)、sz(深交所)下的lday(日线)、fzline(5分钟线)、minline下,扩展名分别为day(日线)、lc5(5分钟)、lc1(1分钟)。

1、通达信日线*.day文件

文件名即股票代码

每32个字节为一天数据

每4个字节为一个字段,每个字段内低字节在前

00 ~ 03 字节:年月日, 32位整型

04 ~ 07 字节:开盘价*100, 32位整型

08 ~ 11 字节:最高价*100, 32位整型

12 ~ 15 字节:最低价*100, 32位整型

16 ~ 19 字节:收盘价*100, 32位整型

20 ~ 23 字节:成交额(元),float型

24 ~ 27 字节:成交量(股),32位整型

28 ~ 31 字节:预留

2、通达信5分钟线*.lc5文件和1分钟线*.lc1

文件名即股票代码

每32个字节为一个5分钟数据,每字段内低字节在前

00 ~ 01 字节:日期,整型,设其值为num,则日期计算方法为:

year=floor(num/2048)+2004;

month=floor(mod(num,2048)/100);

day=mod(mod(num,2048),100);

02 ~ 03 字节: 从0点开始至目前的分钟数,整型

04 ~ 07 字节:开盘价,单精度浮点数

08 ~ 11 字节:最高价,单精度浮点数

12 ~ 15 字节:最低价,单精度浮点数

16 ~ 19 字节:收盘价,单精度浮点数

20 ~ 23 字节:成交额*100,float型

24 ~ 27 字节:成交量(股),整型

28 ~ 31 字节:(保留)

本实例针对日线和分钟线分别做成两个读取函数,读取的数据存放在matlab的table文件,存储为.Mat,方便下次调用。由于每只股票一个文件,需要采用严格的目录管理加以管理。

function readday(infile)

%%

%{读取通达信盘后日线数据

% 文件名:股票代码

% 每32个字节为一个日线数据,每字段内低字节在前

% 00 ~ 03 字节:日期,整型;

% 04 ~ 07 字节:开盘价,整型

% 08 ~ 11 字节:最高价,整型

% 12 ~ 15 字节:最低价,整型

% 16 ~ 19 字节:收盘价,整型

% 20 ~ 23 字节:成交额,float型

% 24 ~ 27 字节:成交量(股),整型

% 28 ~ 31 字节:(保留)%}

tic

MainPath = ‘\\Stock’;

DataBasePath = '\\DataBasePath';

lx = infile(end-2:end);

fn = infile(1:end-4);

if strcmp(lx,'day')

p = ['D:\\',MainPath,DataBasePath,'\\Daily\\',fn,'.mat'];

else

return;

end;

fid=fopen(infile,'r');

fseek(fid,0,'bof');

clear lc5

ps=fread(fid,[8,inf],'int32'); %读按每个数据4个字节取全部数据,,精度为int32

%取其中的日期和开盘、最高、最低、收盘、成交量,

ps = ps';

year = num2str(floor(ps(:,1)/10000)); %提取年信息

mon = num2str(floor(mod(ps(:,1),10000)/100),'d'); %提取月信息

day = num2str(mod(mod(ps(:,1),10000),100),'d'); %提取日信息

n = length(year);

for i = 1:n

dstr(i,:) = [year(i,:),'-',mon(i,:),'-',day(i,:)];

end;

fseek(fid,0,'bof');

ps1=fread(fid,[8,inf],'single'); %读按每个数据取4个字节取全部数据,,精度为单精度浮点型

%取其中的成交额,

ps1 = ps1';

colName = {'date','open','high','low','close','volume','amount'};

dayl =

table(dstr,ps(:,2)./100,ps(:,3)./100,ps(:,4)./100,ps(:,5)./100,ps(:,7),ps1(:,6),'VariableNames',colName);

fclose(fid);

eval_r([fn,' = dayl']);

save (p,fn);

toc

function readlc(infile)

%%

%{读取通达信盘后分钟数据

% 文件名:股票代码

% 每32个字节为一个分钟数据,每字段内低字节在前

% 00 ~ 01 字节:日期,整型,设其值为num,则日期计算方法为:

% year=floor(num/2048)+2004;

% month=floor(mod(num,2048)/100);

% day=mod(mod(num,2048),100);

% 02 ~ 03 字节: 从0点开始至目前的分钟数,整型

% 04 ~ 07 字节:开盘价,single

% 08 ~ 11 字节:最高价,single

% 12 ~ 15 字节:最低价,single

% 16 ~ 19 字节:收盘价,single

% 20 ~ 23 字节:成交额*100,float型

% 24 ~ 27 字节:成交量(股),整型

% 28 ~ 31 字节:(保留)%}

MainPath = ‘\\Stock’;

DataBasePath = '\\DataBasePath';

lx = infile(end-2:end);

fn = infile(1:end-4);

if strcmp(lx,'lc1')

p = ['D:\\',MainPath,DataBasePath,'\\Min\\',fn,'.mat'];

elseif strcmp(lx,'lc5')

p = ['D:\\',MainPath,DataBasePath,'\\5Min\\',fn,'.mat'];

else

return;

end;

fid=fopen(infile,'r');

fseek(fid,0,'bof');

clear lc5

date=fread(fid,[16,inf],'uint16'); %读按每个数据取2个字节取全部数据,,精度为uint16

%取其中日期和时间数据

date = date';

year = num2str(floor(date(:,1)/2048)+2004); %提取年信息

mon = num2str(floor(mod(date(:,1),2048)/100),'d'); %提取月信息

day = num2str(mod(mod(date(:,1),2048),100),'d'); %提取日信息

n = length(year);

for i = 1:n

dstr(i,:) = [year(i,:),'-',mon(i,:),'-',day(i,:)];

end;

tm=floor(date(:,2)/60)*100+mod(date(:,2),60); %转为几点(千、百位)几分(十、个位)

fseek(fid,0,'bof');

ps=fread(fid,[8,inf],'single'); %读按每个数据取4个字节取全部数据,,精度为单精度浮点型

%取其中的开盘、最高、最低、收盘、成交额,

ps = ps';

fseek(fid,0,'bof');

ps2=fread(fid,[8,inf],'int32'); %读按每个数据取4个字节取全部数据,,精度为int32

%只取其中的成交量数据,

ps2=ps2';

colName = {'dat','time','open','high','low','close','volume','amount'}

lc

table(dstr,tm,ps(:,2),ps(:,3),ps(:,4),ps(:,5),ps2(:,7),ps(:,6),'VariableNames',colName);

=

fclose(fid);

eval_r([fn,' = lc']);

save (p,fn);

由于matlab不能直接读取结构数据,本实例根据不同数据精度多次读取到数组的方法,由于每次读取数据实际上是在内存中进行,并不会太大影响读取速度。比for循环逐条读取速度快得多。当如果网友有更好办法,欢迎留言。

使用该实例的时候,注意源文件的路径。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- axer.cn 版权所有 湘ICP备2023022495号-12

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务