MATLAB中的内存映射文件?

Jam*_*her 6 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)
Run Code Online (Sandbox Code Playgroud)

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

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

以下是我的数据文件的一些较小版本,以便人们可以理解我的数据结构:

詹姆斯欢呼

Die*_*ter 5

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

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

好的,那么如何阅读你的文件memmapfile这篇文章提供了一些提示.

所以首先我们打开你的文件'uint8'(注意没有'char'选项,所以我们将文件的内容读入相同大小的数据类型的解决方法):

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

我们可以通过将数据转换为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
Run Code Online (Sandbox Code Playgroud)

由于文件中的每一行具有相同的长度(数字的2*8个字符,1个制表符和2个字符,用于换行符= 19个字符),我们可以N通过读取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
Run Code Online (Sandbox Code Playgroud)

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

d = reshape(f,2,[]).'
d =
    0.3985    0.0634
    0.3996    0.0633
    0.3990    0.0613
Run Code Online (Sandbox Code Playgroud)

比使用更简单的方法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.
Run Code Online (Sandbox Code Playgroud)

使用此功能,您可以一次读取一Nlines对值,处理它们,然后fread再次调用以读取下一个值Nlines.fread记住它在文件中的位置(如同fscanf),所以只需使用相同的调用即可获得下一行.因此很容易编写一个循环来处理整个文件,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);
Run Code Online (Sandbox Code Playgroud)

但请注意,fread接下来sscanf将是最快的.但请注意,fread只要文本文件中有一行与您的格式不完全匹配,该方法就会死亡.textscan另一方面,对空白的变化是宽容的,因此更加健壮.