2010-02-26 11 views
5

Necesito analizar los bytes de un archivo para que solo tome los datos después de que se haya identificado una determinada secuencia de bytes. Por ejemplo, si la secuencia es simplemente 0xFF (un byte), entonces puedo utilizar LINQ en la colección:Cómo localizar una secuencia de valores (específicamente, bytes) dentro de una colección más grande en .NET

byte[] allBytes = new byte[] {0x00, 0xFF, 0x01}; 
var importantBytes = allBytes.SkipWhile(byte b => b != 0xFF); 
// importantBytes = {0xFF, 0x01} 

Pero, ¿existe una manera elegante para detectar una secuencia de varios bytes - por ejemplo, 0xFF, 0xFF: ¿especialmente uno que retrocede en caso de que comience a obtener una coincidencia falsa positiva?

Respuesta

1

No conozco ninguna forma incorporada; como de costumbre, siempre puedes escribir tu propio método de extensión. Aquí está uno de la parte superior de la cabeza (puede haber formas más eficientes para ponerla en práctica):

public static IEnumerable<T> AfterSequence<T>(this IEnumerable<T> source, 
    T[] sequence) 
{ 
    bool sequenceFound = false; 
    Queue<T> currentSequence = new Queue<T>(sequence.Length); 
    foreach (T item in source) 
    { 
     if (sequenceFound) 
     { 
      yield return item; 
     } 
     else 
     { 
      currentSequence.Enqueue(item); 

      if (currentSequence.Count < sequence.Length) 
       continue; 

      if (currentSequence.Count > sequence.Length) 
       currentSequence.Dequeue(); 

      if (currentSequence.SequenceEqual(sequence)) 
       sequenceFound = true; 
     } 
    } 
} 

Voy a tener que comprobar para asegurarse de que esto es correcto, pero debe darle la idea básica; iterar a través de los elementos, seguir la última secuencia de valores recuperados, establecer un indicador cuando se encuentra la secuencia, y una vez que se establece el indicador, comience a devolver cada elemento posterior.

Editar - Hice una prueba, y funciona correctamente. Aquí hay algunos códigos de prueba:

static void Main(string[] args) 
{ 
    byte[] data = new byte[] 
    { 
     0x01, 0x02, 0x03, 0x04, 0x05, 
     0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA 
    }; 
    byte[] sequence = new byte[] { 0x02, 0x03, 0x04, 0x05 }; 
    foreach (byte b in data.AfterSequence(sequence)) 
    { 
     Console.WriteLine(b); 
    } 
    Console.ReadLine(); 
} 
1

Si convierte sus bytes en una cadena, puede aprovechar la gran cantidad de funciones de búsqueda integradas en ella, incluso si los bytes con los que está trabajando no son realmente caracteres en el sentido tradicional.

+0

¿No tiene que preocuparse de lo que podría suponer .NET sobre la codificación y tales que daría resultados erróneos? – thelsdj

+0

Creo que mientras busque una secuencia de bytes exacta, la codificación realmente no importará (siempre que tanto la fuente como la secuencia de búsqueda tengan la misma codificación). Puede usar la clase ASCIIEncoding para ayudar a convertir de ida y vuelta. – MikeP

Cuestiones relacionadas