我决定使用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是我的数据文件的一些较小版本,因此人们可以了解我的数据的结构:
欢呼声 詹姆斯
答案 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
以阅读下一个fread
。 Nlines
会记住文件中的位置(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
是对空白变化的宽容,因此更加健壮。