在C#中是否有与mmap.mmap.rfind相同的东西?

时间:2018-01-23 16:05:34

标签: c# python-3.x translate

在查看C#中的内存映射文件时,确定如何快速向前和向后搜索文件存在一些困难。我的目标是在语言中重写以下函数,但是找不到任何内容,例如下面使用的findrfind方法。在C#中有一种方法可以使用特定的子字符串快速搜索内存映射文件吗?

#! /usr/bin/env python3
import mmap
import pathlib


# noinspection PyUnboundLocalVariable
def drop_last_line(path):
    with path.open('r+b') as file:
        with mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as search:
            for next_line in b'\r\n', b'\r', b'\n':
                if search.find(next_line) >= 0:
                    break
            else:
                raise ValueError('cannot find any line delimiters')
            end_1st = search.rfind(next_line)
            end_2nd = search.rfind(next_line, 0, end_1st - 1)
        file.truncate(0 if end_2nd < 0 else end_2nd + len(next_line))

1 个答案:

答案 0 :(得分:1)

  

C#中有没有办法使用特定的子字符串快速搜索内存映射文件?

     

您是否知道在C#中对整个文件进行内存映射,然后将其视为字节数组?

是的,将整个文件映射到视图然后将其读入单个byte数组非常容易,如下面的代码所示:

static void Main(string[] args)
{
    var sourceFile=  new FileInfo(@"C:\Users\Micky\Downloads\20180112.zip");
    int length = (int) sourceFile.Length;  // length of target file

    // Create the memory-mapped file.
    using (var mmf = MemoryMappedFile.CreateFromFile(sourceFile.FullName,
                                                     FileMode.Open, 
                                                     "ImgA"))
    {
        var buffer = new byte[length]; // allocate a buffer with the same size as the file

        using (var accessor = mmf.CreateViewAccessor())
        {
            var read=accessor.ReadArray(0, buffer, 0, length); // read the whole thing
        }

        // let's try searching for a known byte sequence.  Change this to suit your file
        var target = new byte[] {71, 213, 62, 204,231};

        var foundAt = IndexOf(buffer, target);

    }
}

我似乎无法在MarshalArray中找到任何字节搜索方法,但您可以使用社交的 courtesy 搜索算法MSDN 作为开始:

private static int IndexOf2(byte[] input, byte[] pattern)
{
    byte firstByte = pattern[0];
    int  index     = -1;

    if ((index = Array.IndexOf(input, firstByte)) >= 0)
    {
        for (int i = 0; i < pattern.Length; i++)
        {
            if (index + i  >= input.Length ||
                pattern[i] != input[index + i]) return -1;
        }
    }

    return index;
}

...甚至这个更详细的例子(也是社交MSDN,同一链接)

public static int IndexOf(byte[] arrayToSearchThrough, byte[] patternToFind)
{
    if (patternToFind.Length > arrayToSearchThrough.Length)
        return -1;
    for (int i = 0; i < arrayToSearchThrough.Length - patternToFind.Length; i++)
    {
        bool found = true;
        for (int j = 0; j < patternToFind.Length; j++)
        {
            if (arrayToSearchThrough[i + j] != patternToFind[j])
            {
                found = false;
                break;
            }
        }
        if (found)
        {
            return i;
        }
    }
    return -1;
}