Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 快速搜索一组元素_C#_.net_Algorithm_.net 4.0_Io - Fatal编程技术网

C# 快速搜索一组元素

C# 快速搜索一组元素,c#,.net,algorithm,.net-4.0,io,C#,.net,Algorithm,.net 4.0,Io,我试图在硬盘上搜索一堆文件,寻找二进制模式。我曾试图用.net中内置的东西找到一些方法,但我似乎找不到任何东西可以让我搜索一组数据,而不是一个字节的数据,除非我先将二进制数据转换成字符串,然后使用string.IndexOf(string value) 我正在写我自己的Boyer Moor流搜索算法,但我想我应该先检查一下这里,以防我错过了一个有效的方法 这是我目前只搜索文本的方法,它工作得很好,我只是不知道如何搜索二进制模式 private string _string; private by

我试图在硬盘上搜索一堆文件,寻找二进制模式。我曾试图用.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);
        }
    }
}
私有字符串\u字符串;
专用字节[]_数组;
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
Parallel.ForEach(Directory.EnumerateFiles(_folder、_filter、SearchOption.AllDirectories)
,搜索);
}
专用无效搜索(字符串文件路径)
{
如果(数字)
{
var fileBinary=File.ReadAllBytes(文件路径);
if(fileBinary.MagicFunctionToDoContains(_array))//这里需要帮助吗
{
lbResults.BeginInvoke(新操作(AddResult),filePath);
}
}
其他的
{
var fileText=File.ReadAllText(filePath,Encoding.ASCII);
if(fileText.IndexOf(_string,StringComparison.OrdinalIgnoreCase)>=0)
{
lbResults.BeginInvoke(新操作(AddResult),filePath);
}
}
}
字节数组的最大值不超过8个字节,如果这影响建议,则通常情况下为4个字节


是否有任何内置到.net或预先编写的示例可以用来完成此任务?

我不知道.net Framework中有任何东西可以完成您试图使用byte[]完成的任务。但我认为一个简单的解决方案是将每个字节转换为char,然后将char[]转换为字符串;因此,您可以将文件数据转换为char[],然后转换为字符串,以及正在搜索的数据,然后使用.Net中内置的字符串搜索算法。这将节省使用您自己的模式搜索算法的时间,而且如果数据不太大,开销应该可以忽略不计。

编写Boyer-Moor算法应该很简单。然而,对于如此短的模式(4-8字节),我怀疑您是否看到了与逐字节搜索相比的性能提升


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

是否要按磁盘上的文件进行搜索,或者您想建立一个索引,然后使用该索引进行搜索

  • 如果是前者,我看不出Boyer–Moore不能在字节“字符”上实现的原因
  • 如果是后者,则需要一个专门的数据结构,如后缀树
顺便说一句,从性能角度来看,加载整个文件的内容可能不是最好的主意-如果您碰巧遇到一个多GB的视频文件,该怎么办?由于您所做的只是线性遍历文件内容,因此可以逐块加载它


为了实现真正的性能,将搜索和块加载分离到并发线程(或者更好的是,TPL
Task
s)中,队列(块)介于两者之间。并行读取多个文件以利用大多数现代磁盘控制器中实现的本机命令队列甚至可能有一些好处(但仅对于机械磁盘,SSD不受益于NCQ).

他们甚至可以使用内存映射文件来帮助划分大文件的工作。此外,还有任何内置函数可以对两个数组进行“逐字节”比较,而不是将任意二进制数据解析为字符串。字符串必须遵循Unicode约定,某些值是非法的。此外,比较的表现也不同。