zoukankan      html  css  js  c++  java
  • Matlab 用fread、fwrite实现大文件读写

    最近在分析一个35G的大数据文件,猛一看,是不是很吓人啊,不过还好,师兄写文件的格式非常规范,读取数据来也就很方便了,主要是使用了读写文件的两个函数fread和fwrite,下面用matlab简单尝试一下,对于这种文件读取的低级函数,c和matlab功能都是差不多的。

    先来看fwrite,最简单的用法如下

    %%

    x = 1:15;

    dataw = reshape(x, 5, 3);

    disp(dataw)

    %%

    filename = 'test.bin';

    hfile = fopen(filename, 'w');

    fwrite(hfile, dataw, 'double');

    fclose(hfile);

    fwrite写矩阵,是按列来写的,即先写第一列,再第二列,以此类推。如上面的代码,x为

    1     6    11

    2     7    12

    3     8    13

    4     9    14

    5    10    15

    如果把数据全部读出来,就是

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

     

    稍复杂的写法是,可以跳着写,就是每个数据先跳几个位置,然后再写数据,如上面的5X3矩阵,如果想按行来写,当然最简单的方式是先转置一下再写,但如果数据量非常大,而且还在另一个文件里,总不能先都读取进来,再转置、写,当然这只是一种特殊情况,但跳着写在某些时候确实是好的解决方法,如下实现按行写

    %%

    x = 1:15;

    dataw = reshape(x, 5, 3);

    disp(dataw)

    len = 5;

    count = 3;

    %%

    filename = 'test.bin';

    hfile = fopen(filename, 'w');  

    fwrite(hfile, zeros(count, 1), 'double'); % 先写一行0,因为fwrite总是先跳再写,对于第一行也要先跳,那就先在第一行补个零吧

    for i = 1:count

        fseek(hfile, 8*i, 'bof'); % 常常要配合fseek使用 fseek(fid,offset,origin);

    % double matlab 中是 'real*8' 表示64位共8字节的浮点数

    %所以上面的fwrite(hifle,zeros(count,….) 写入了24个字节的数据

    %因为fwrite写入数据后会把当前指针hfile移动到最后一个字节位置, 所以此时ftell(hfile)就为24

        fwrite(hfile, dataw(1:end, i), 'double', 8*(count-1)); % fwrite(fid,A,precision,skip)

    %fwrite(hfile,dataw(1:end,1),…)这一行表示将dataw矩阵中的第一列数据1 2 3 4 5 每隔16个字节(因为这里用的double型,每个数据位占用了8字节)写入一个数据

    %因为fwrite()是先跳后写入,即在写入dataw中第一列的第一个数据值1之前hfile在当前指针所指字节数的位置向前跳8*(count-1)个字节,然后写入这个数值1(这个1占用了8个字节,共64位),然后再跳8*(count-1)个字节,接着写入数值2dataw的第一列第二个值),直到把这列数据写完!然后继续循环

        %dataw(1:end,i)表示取矩阵的第i列,可写为dataw(:,i)

    end

    fclose(hfile);

    hfile = fopen(filename, 'r');

    datar = fread(hfile, 100, 'double')

    fclose(hfile);

    结果如下

         1     6    11

         2     7    12

         3     8    13

         4     9    14

         5    10    15

    datar =

         0

         0

         0

         1

         6

        11

         2

         7

        12

         3

         8

        13

         4

         9

        14

         5

        10

        15

     

    fwrite写的文件再配合上fread读,那真是天作之合了,35G的数据也是浮云啊!

    最简单的读取方式就是上面的

    datar = fread(hfile, 100, 'double')

    直接读取100个数据。当然更灵活的是跳着读,如下面的程序

    %%

    x = 1:15;

    dataw = reshape(x, 5, 3);

    disp(dataw)

    %%

    filename = 'test.bin';

    hfile = fopen(filename, 'w');

    fwrite(hfile, dataw, 'double');

    fclose(hfile);

    %% 跳着读

    ind = 2; % 读第几时刻的数据

    len = 5; % 一次数据的长度

    hfile = fopen(filename, 'r');

    fseek(hfile, 8*(ind - 1), 'bof');

    datar = fread(hfile, 3, 'double', 8*(len - 1)); % double为8个字节

    fclose(hfile);

    disp(datar)

    结果如下

    1     6    11

    2     7    12

    3     8    13

    4     9    14

    5    10    15

    2

    7

    12

    这意思就是,文件中存储的数据为1到15,但如果我想读取上面矩阵中的第一行,即1,6,11,那就可以跳着读,但注意跳着读时,第一个数据是不跳直接读的,帮助里的说明是skips skip bytes after reading each value,这是和fwrite不同的地方,skips skip bytes before writing each value,所以上面fwrite跳着写的时候要先补一下0,再跳着写,方便一些。

     

    源文档 <http://blog.sina.com.cn/s/blog_6163bdeb0102dqtk.html>

  • 相关阅读:
    git——学习笔记(一)
    技术大牛的博客//文档
    python——周边
    数据挖掘算法:关联分析二(Apriori)
    数据挖掘算法:关联分析一(基本概念)
    Python入门5(pandas中merge中的参数how)
    Spark入门3(累加器和广播变量)
    Spark入门2(Spark简析)
    Spark入门1(以WordCount为例讲解flatmap和map之间的区别)
    算法入门1(决策树)
  • 原文地址:https://www.cnblogs.com/AI-Algorithms/p/3674457.html
Copyright © 2011-2022 走看看