C # Бинарный поиск + замена - PullRequest
0 голосов
/ 18 ноября 2018

Как я могу найти указанный байтовый массив и заменить все от начала до этого байтового массива (входит в комплект)

В основном у меня есть шаблон для поиска

byte[] find = { 0x00, 0x48, 0x00 };

и

byte[] ddsHeaderDXT1 = { 0x44, 0x44, 0x53, 0x20, 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x56, 0x54, 0x54, 0x06, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x44, 0x58, 0x54, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };

что я хочу сделать, так это найти мой массив find, как только он будет найден, выбрать все байты от начала файла до включенного массива find и заменить все это на мой ddsHeaderDXT1 массив.Файл может быть довольно большим, но шаблон всегда находится в начале (менее 500 первых байтов), не всегда с одинаковым смещением и может быть найден только один раз.

Я уже пробовал код Рене здесь но это ничего не делает.Также я получаю свой файл от OpenFileDialog и читаю его байты

byte[] src = File.ReadAllBytes(ofdFilePath);

1 Ответ

0 голосов
/ 18 ноября 2018

Следующее должно сделать трюк:

public static bool TryFindAndReplace<T>(
    T[] source,
    T[] pattern,
    T[] replacement,
    out T[] newArray)
{
    if (source == null)
        throw new ArgumentNullException(nameof(source));

    if (pattern == null)
        throw new ArgumentNullException(nameof(pattern));

    if (replacement == null)
        throw new ArgumentNullException(nameof(replacement));

    newArray = null;

    if (pattern.Length > source.Length)
        return false;

    for (var start = 0; 
         start < source.Length - pattern.Length + 1; 
         start += 1)
    {
        var segment = new ArraySegment<T>(source, start, pattern.Length);

        if (Enumerable.SequenceEqual(segment, pattern))
        {
            newArray = replacement.Concat(source.Skip(start + pattern.Length))
                                  .ToArray();
            return true;
        }
    }

    return false;
}

Простой для чтения и, следовательно, простой для понимания. Это не самое быстрое решение, но все должно быть так быстро, как вам нужно, а не быстрее.

Если вам нужна более производительная реализация, вы можете оптимизировать ее здесь.

...