快速搜索一组元素

时间:2011-10-17 17:38:08

标签: c# .net algorithm .net-4.0 io

我正在尝试在硬盘上搜索一堆文件以获取二进制模式。我试图找到一些方法来使用.net中内置的东西来做这件事,但我似乎无法找到任何可以让我搜索一组数据的东西,而不只是一个字节的数据,除非我转换我的首先将二进制数据放入字符串并使用String.IndexOf(string value)

我正在编写自己的Boyer-Moor流搜索算法的一半,但我想我应先检查一下,以防我错过了有效地做到这一点的方法。

这是我目前只针对文本进行搜索的方法,它运行得很好,我只是不知道如何处理二进制模式

private string _string;
private byte[] _array;

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    Parallel.ForEach(Directory.EnumerateFiles(_folder, _filter, SearchOption.AllDirectories)
        , Search);
}

private void Search(string filePath)
{

    if (numbers)
    {
        var fileBinary = File.ReadAllBytes(filePath);
        if (fileBinary.MagicFunctionToDoContains(_array)) //Need help here
        {
            lbResults.BeginInvoke(new Action<string>(AddResult), filePath);
        }
    }
    else
    {
        var fileText = File.ReadAllText(filePath, Encoding.ASCII);
        if (fileText.IndexOf(_string, StringComparison.OrdinalIgnoreCase) >= 0)
        {
            lbResults.BeginInvoke(new Action<string>(AddResult), filePath);
        }
    }
}

字节数组最大不会超过8个字节,常见情况是4个字节,如果这会影响建议。

.net或预编写的示例中是否有内置的内容可用于执行此操作?

3 个答案:

答案 0 :(得分:1)

编码Boyer-Moor算法应该很简单。但是,对于这种短模式(4-8字节),我怀疑与逐字节搜索相比,你会看到更多的性能提升。

为提高性能,您可以使用unsafefixed关键字来使用指针算法,因为每次访问 fileBinary时,数组索引器都会检查索引变量数组。

答案 1 :(得分:1)

您是要搜索磁盘上的文件,还是要构建索引,然后使用该索引进行搜索?

  • 如果是前者,我看不出Boyer-Moore无法在字节“字符”上实现的原因。
  • 如果是后一种情况,则需要一个专门的数据结构,例如后缀树。
BTW,加载整个文件的内容可能不是最佳的性能明智 - 如果碰巧遇到多GB视频文件怎么办?由于您所做的只是线性遍历文件内容,因此您可以逐块加载它。

对于一个真正高效的实现,将搜索和块加载分成并发线程(或者更好的是,TPL Task s),其间有队列(块)。使用大多数现代磁盘控制器中实现的本机命令队列并行读取多个文件甚至可能有一些好处(但仅限于机械磁盘,SSD不会受益于NCQ)。

答案 2 :(得分:0)

我不知道.Net Framework中的任何内容都会使用byte []完成您要完成的任务。但我认为一个简单的解决方案是将每个字节转换为char,然后将char []转换为字符串;因此,您可以将filedata转换为char [],然后将字符串以及您要搜索的数据转换为.Net,然后使用字符串搜索算法构建到.Net中。它可以节省滚动自己的模式搜索算法的时间,如果数据不是很大,开销应该可以忽略不计。