MATLAB中的内存映射文件?

时间:2014-01-06 15:12:09

标签: matlab bigdata

我决定使用memmapfile,因为我的数据(通常为30Gb到60Gb)太大而无法放入计算机的内存中。

我的数据文件包含两列数据,对应两个传感器的输出,我有.bin和.txt两种格式。

m=memmapfile('G:\E-Stress Research\Data\2013-12-18\LD101_3\EPS/LD101_3.bin','format','int32')
m.data(1)

我使用上面的代码将我的数据存储到变量“m”,但我不知道使用什么数据格式(int8','int16','int32','int64','uint8',' uint16','uint32','uint64','single'和'double')。 事实上,我尝试了MATLAB支持的所有数据格式,但是当我使用m.data(索引号)时,我从来没有得到一对数字(2列数据),这是我的预期,也就是数字根据我使用的格式不同。

如果有人有memmapfile的经验,请帮助我。

Here是我的数据文件的一些较小版本,因此人们可以了解我的数据的结构:

欢呼声 詹姆斯

1 个答案:

答案 0 :(得分:5)

memmapfile用于读取二进制文件,这就是您遇到文本文件问题的原因。其中的数据是字符,因此您必须将它们作为字符读取,然后将它们解析为数字。更多关于以下内容。

二进制文件似乎不仅包含以二进制格式写入的浮点值流。我也看到了文件中的标识符(字符串)和其他内容。您唯一的阅读希望是联系创建二进制文件的设备的制造商,并询问他们如何阅读这些文件。可能会有一个SDK,或者至少是格式的描述。您可能希望查看此内容,因为文本文件中的浮点数可能会被截断,即与直接读取浮点数的二进制表示相比,您丢失了精度。

好的,那么如何使用memmapfile阅读您的文件? This post提供了一些提示。

首先我们将您的文件打开为'uint8'(请注意,没有'char'选项,因此我们将文件内容读入相同大小的数据类型中作为解决方法:

m = memmapfile('RTL5_57.txt','Format','uint8'); % uint8 is default, you could leave that off

我们可以通过将数据转换为char来将读取的数据作为uint8读入:

c = char(m.Data(1:19)).' % read the first three lines. NB: transpose just for getting nice output, don't use it in your code
c = 
    0.398516    0.063440
    0.399611    0.063284
    0.398985    0.061253

由于文件中的每一行都有相同的长度(数字为2 * 8个字符,新行为1个标签和2个字符= 19个字符),我们可以通过阅读{{{}来读取文件中的N行1}}值。因此,N*19会为您提供第一行m.Data(1:19),第二行和m.Data(20:38)第二行和第三行。一次阅读尽可能多的内容。

然后我们必须将读入数据解析为浮点数:

m.Data(20:57)

现在剩下的就是将它们重塑为两列格式

f = sscanf(c,'%f')
f =
    0.3985
    0.0634
    0.3996
    0.0633
    0.3990
    0.0613

比使用d = reshape(f,2,[]).' d = 0.3985 0.0634 0.3996 0.0633 0.3990 0.0613 更简单: 您不需要使用memmapfile来解决问题,我认为这会使事情变得更复杂。您只需使用memmapfile后跟fopen

即可
fread

使用此功能,您可以一次阅读fid = fopen('RTL5_57.txt'); c = fread(fid,Nlines*19,'*char'); % now sscanf and reshape as above % NB: one can read the values the text file directly with f = fscanf(fid,'%f',Nlines*19). % However, in testing, I have found calling fread followed by sscanf to be faster % which will make a significant difference when reading such large files. 个值对,处理它们,然后再次致电Nlines以阅读下一个freadNlines会记住文件中的位置(fread也是如此),因此只需使用相同的调用即可获得下一行。因此,编写一个循环来处理整个文件很容易,如果你在文件的末尾就用fscanf进行测试。

建议使用更简单的方式here:使用feof(fid)。稍微调整他们的示例代码:

textscan

但请注意,Nlines = 10000; % describe the format of the data % for more information, see the textscan reference page format = '%f\t%f'; fid = fopen('RTL5_57.txt'); while ~feof(fid) C = textscan(fid, format, Nlines, 'CollectOutput', true); d = C{1}; % immediately clear C at this point if you need the memory! % process d end fclose(fid); 后跟fread的速度最快。但请注意,只要文本文件中有一行与您的格式不完全匹配,sscanf方法就会死亡。另一方面,fread是对空白变化的宽容,因此更加健壮。