Javascript 在类型化数组中查找字节序列,而无需编写Boyer-Moore实现
我必须在用户加载的文件中找到一些标记(文本序列)。这些文件中有85%是UTF-8编码的文本,但也会有二进制文件。标记现在是文本序列,但将来可能会使用正则表达式(可能不会用于二进制文件,但我还不知道) 我的文件内容是Javascript 在类型化数组中查找字节序列,而无需编写Boyer-Moore实现,javascript,fileapi,arraybuffer,typed-arrays,Javascript,Fileapi,Arraybuffer,Typed Arrays,我必须在用户加载的文件中找到一些标记(文本序列)。这些文件中有85%是UTF-8编码的文本,但也会有二进制文件。标记现在是文本序列,但将来可能会使用正则表达式(可能不会用于二进制文件,但我还不知道) 我的文件内容是ArrayBufferarrays,我必须在该数据中找到标记。我有以下选择: 使用类型化数组(UInt8Array)和textdecker('ascii'),并对解码数据使用String.indexOf()。我不喜欢这样,因为至少在原则上,这可以复制textdecker.decode(
ArrayBuffer
arrays,我必须在该数据中找到标记。我有以下选择:
UInt8Array
)和textdecker('ascii')
,并对解码数据使用String.indexOf()
。我不喜欢这样,因为至少在原则上,这可以复制textdecker.decode()之后文件内容使用的内存。但这很简单,也很简单。也适用于二进制文件,因为标记将是二进制数据中的ASCII字节
UInt8Array
),编写自己版本的Boyer Moore或其他快速字符串搜索函数,以查找所需的字节序列。快速,内存优化。。。但我不想再写一个Boyer Moore实现或复制一个。记住,将来我可能会使用正则表达式,所以ArrayBuffer
,因为它们中有85%是UTF-8编码的文本,并尝试使用我将遇到的几个真正的二进制文件做一些特别的事情。这意味着我可以从一开始就使用正则表达式或String.indexOf()
,这没什么大不了的,但另一方面,在找到标记后处理二进制文件可能是个问题,因为原始数据将转换为文本提前谢谢 您可以将数组缓冲区解码为文本流。
有一个,但FF中仍然不支持它,它需要在Blob中复制ArrayBuffers,以便对其进行流式传输 因此,在使用ArrayBuffers的情况下,您可以使用该方法的
stream
选项,并按小块读取ArrayBuffer:
const buffer_1=new textcoder().encode(“AAABCBAB”).buffer;
//预期指数:[2,6]^^
常量索引_1=获取索引(缓冲区_1,“AB”,每次3/*3字节*/);
log(“缓冲区1”,
JSON.stringify(索引_1),
//检查他们是否都是“AB”
stringify(提取内容(缓冲区1,索引1,2))
);
//更复杂的测试,使用随机二进制数据(读作UTF-8)
常量缓冲区_2=uint32数组自(
{长度:1024*1024},
()=>Math.random()*0xFFFFFFFF
).缓冲器;
常量索引_2=获取索引(缓冲区_2,“AB”);
log(“缓冲区2”,
JSON.stringify(索引_2),
//检查他们是否都是“AB”
stringify(提取内容(缓冲区2,索引2,2))
);
函数getAllIndices(缓冲区、标记、chunksize=1024/*字节*/){
如果(!marker){return null;}
if(!(RegExp的标记实例)){
marker=新的RegExp(marker,“g”);
}
marker.global=true;
//标记可以分为两块。
//因此,在每一块中,我们都会预加最后几个字符
//最后一块。
常量标记长度=marker.source.length;
常量位置=[];
const arr=新的Uint8Array(缓冲区);
const decoder=新文本解码器();
设当前_指数=0;
设全长=0;
让标记_buffer=“”;
while(当前_指数-1?
(最后索引+标记长度):
(解码长度-标记长度);
marker\u buffer=解码的.slice(marker\u索引);
}
返回位置;
}
//仅供演示
函数提取内容(缓冲区、索引、长度){
const full_str=新文本解码器()。解码(缓冲区);
返回index.map((index)=>full_str.slice(index,index+length));
}
是的,我知道,我可能在这里工作过度,可能textdecker
不会像我想的那样消耗内存。事实上,我所做的测试表明了这一点。但无论如何,我想在这里看到更多的选择,只是为了确保我没有遗漏一些明显的东西…Kaido,这是你今天第二次帮助我,非常感谢你提供的信息和代码。我知道TextDecoderStream,但是代码必须在FF中工作,所以我拒绝了它,并且我不知道stream选项。我已经读了很多次说明书,以至于我对这些信息视而不见。我想我可以修改代码,这样我将处理的标记就不会太麻烦了,希望如此。由于标记在最初的几个kb中,比如90%的时间,我可以使用stream选项并为边缘情况定制一些解决方案。非常感谢,真的。