我有大型二进制文件(2+ GB),这些文件以同步模式(0xDEADBEEF)排列,后跟固定大小的数据块。 例如:
0xDE AD BE EF ... 96 bytes of data
0xDE AD BE EF ... 96 bytes of data
... repeat ...
我需要找到每个数据包开头的偏移量。理想情况下,这只是[1:packetSize:fileSize]
但是,还有其他数据可以散布,标题等。所以我需要在文件中搜索同步模式。
我正在使用以下基于Loren from Mathworks findPattern2的代码,但稍微修改了一下以使用内存映射。
function pattLoc = findPattern(fileName, bytePattern)
%Mem Map file
m = memmapfile(fileName);
% Find candidate locations match the first element in the pattern.
pattLoc = find(m.data==bytePattern(1));
%Remove start values that are too close to the end to possibly match
len = numel(bytePattern);
endVals = pattLoc+len-1;
pattLoc(endVals>length(m.data)) = [];
% loop over elements of Sync Pattern to check possible location validity.
for pattval = 2:len
% check viable locations in array
locs = bytePattern(pattval) == m.data(pattLoc+pattval-1);
pattLoc(~locs) = []; % delete false ones from indices
end
这非常有效。但是,我认为可能还有改进的余地。首先我知道我的模式不能比packetSize
(本例中为100)更接近但可能更远。似乎我应该能够以某种方式使用此信息来加速搜索。其次,第5行的初始搜索使用find
进行数字索引而不是逻辑。这条线的使用时间几乎是合乎逻辑的两倍。但是,我试图仅使用逻辑索引来重写此函数,并且失败了。问题出现在循环内部并使用逻辑跟踪嵌套索引,而不使用更多查找...或检查比需要更多的数据。
所以任何加快这一点的帮助都会受到赞赏。下面是一些代码,它们将创建一个简单的示例二进制文件,以便在必要时使用。
function genSampleFile(numPackets)
pattern = hex2dec({'DE','AD','BE','EF'});
fileName = 'testFile.bin';
fid = fopen(fileName,'w+');
for f = 1:numPackets
fwrite(fid,[pattern; uint8(rand(96,1)*255)],'uint8');
end
fclose(fid);
使用10000000个数据包搜索文件时需要执行以下操作:
>> genSampleFile(10000000); %Warning Makes 950+MB file
>> tic;pattLoc = findPattern(fileName, pattern);toc
Elapsed time is 4.608321 seconds.
答案 0 :(得分:1)