在ByteArray中定位子数组

问题描述 投票:1回答:1

摘要

正在从文件中读取块中的字节(尚未确定128至1024之间的特定大小,尚未确定),我想搜索缓冲区以查看其是否包含另一个字节数组的签名(模式),以及如果它在缓冲区的最末端找到了某些模式,则应该从文件中读取接下来的几个字节,以查看其是否找到匹配项

我尝试过的事情

public static bool Contains(byte[] buffer, byte[] signiture, FileStream file)
{
    for (var i = buffer.Length - 1; i >= signiture.Length - 1; i--) //move backwards through array stop if < signature
    {
        var found = true; //set found to true at start
        for (var j = signiture.Length - 1; j >= 0 && found; j--) //loop backwards throughsignature
        {
            found = buffer[i - (signiture.Length - 1 - j)] == signiture[j];// compare signature's element with corresponding element of buffer
        }
        if (found)
            return true; //if signature is found return true
    }


    //checking end of buffer for partial signiture
    for (var x = signiture.Length - 1; x >= 1; x--)
    {
        if (buffer.Skip(buffer.Length - x).Take(x).SequenceEqual(signiture.Skip(0).Take(x))) //check if partial is equal to partial signiture
        {
            byte[] nextBytes = new byte[signiture.Length - x];
            file.Read(nextBytes, 0, signiture.Length - x); //read next needed bytes from file
            if (!signiture.Skip(0).Take(x).ToArray().Concat(nextBytes).SequenceEqual(signiture))
                return false; //return false if not a match
            return true; //return true if a match
        }
    }
    return false; //if not found return false
}

这有效,但是我被告知linq运行缓慢,我应该使用Array.IndexOf()。我已经尝试过了,但是不知道如何实现]

c# search buffer streamreader indexof
1个回答
0
投票

您可以使用Span<T>, AsSpanMemoryExtensions.SequenceEqual。后者不是LINQ;它是经过优化的,尤其是对于字节数组。它展开循环并使用不安全的代码来执行MemoryExtensions.SequenceEqual

如果没有使用默认情况下包含这些类型/方法的框架(.Netcore2.1 + ,. Netstandard 2.1),则可以添加memcmp nuget包。 System.Memory的实现略有不同(所谓的“慢版本”),但仍比使用LINQ的SequenceEqual更快。

注意,您还需要检查SequenceEqual的返回值。

FileStream.Read
© www.soinside.com 2019 - 2024. All rights reserved.