7

我有一个 1250 字节长的固定长度字节数组。它可能包含以下类型的数据:

  • 由 5 个字节组成的对象 A。第一个字节包含字母“A”,接下来的四个字节存储一个从 1 到 100000 的整数。

  • 由 2 个字节组成的对象 B。第一个字节包含字母“B”,下一个字节包含一个从 1 到 100 的整数。

  • 由 50 个字节组成的对象 C。所有 50 个字节都用于存储 ASCII 编码的字符串,该字符串数字和以下字符组成:- + ( 和 )

我不知道字节数组中有多少每种对象类型,但我知道它们被组合在一起(对象 B、对象 B、对象 A、对象 A、对象 A、对象 C 等)。大多数时候,当我解析一个字节数组时,该数组包含一种类型的数据(例如,所有项目都是对象 A)所以我确切地知道每个项目由多少个字节组成,我只是循环遍历处理字节的数组. 在这种情况下,我有三种不同类型的数据,它们的长度都不同。我在想我需要做这样的事情:

int offset = 0;
while (offset <= 1250)
{
    string objectHeader = Encoding.ASCII.GetString(byteArray, offset, 1);

    if (objectHeader.Equals("A"))
    {
        // read 4 more bytes and then convert into int value (1 - 100000)
        index += 5;
    }
    else if (objectHeader.Equals("B"))
    {
        // read 1 more byte and then convert into int value (1 - 100)
        index += 2;
    }
    else
    {
        // read 49 more bytes and then convert into a string
        index += 50;
    }
}

有没有更好的方法来做到这一点?

4

2 回答 2

8

好吧,偏移量和索引似乎有点混乱,也许您应该使用for循环:

for(int index = 0; index < 1250; index++)
{
    switch(byteArray[index])
    {
         case (byte)'A':
             index++;
             int value = BitConverter.ToInt32(byteArray, index);
             index += 4;
             break;

       case (byte)'B':
             index++;
             // Read the next byte as integer.
             int value = (int)byteArray[index];
             index++;
             break;

       case (byte)'C':  // string.
             index++;
             // Read the next 49 bytes as an string.
             StringBuilder value = new StringBuilder(49);
             for(int i = index; i < index + 49; index++)
             {
                 if (byteArray[i] == 0) break;
                 value.Append(Converter.ToChar(byteArray[i]));
             }
             index+= 49;
             break;

       case 0:  // Finished.
             index = 1250;
             break;
       default:
             throw new InvalidArgumentException("Invalid byte array format");
    }
}

您如何查看是否没有更多对象?在我的示例中,我建议它以“\0”结尾。

祝你的任务好运。

于 2013-02-05T19:54:06.423 回答
2
      int offset = 0;
      while (offset <= 1250)
      {

        switch (byteArray[offset])
        {
          case (byte)'A':
            //read other data ..
            offset += 5;
            break;
          case (byte)'B':
            //read other data ..
            offset += 2;
            break;
          case (byte)'C':
            //read other data ..
            offset += 50;
            break;
          default:
            //error
            break;
        }
      } 

或带有二进制阅读器的另一种变体:

      var reader = new BinaryReader(new MemoryStream(byteArray), Encoding.ASCII);
      while (reader.BaseStream.Position < reader.BaseStream.Length)
      {
        switch(reader.ReadChar())
        {
          case 'A':
            {
              var i = reader.ReadInt32();
              return new TypeA(i);
            }
            break;
          case 'B':
            {
              var i = reader.ReadByte();
              return new TypeB(i);
            }
            break;
          case 'C':
            {
              var chars = reader.ReadChars(49);
              return new TypeC(new string(chars.TakeWhile(ch => ch != 0).ToArray()));
            }
            break;
        }

      }
于 2013-02-05T19:51:05.337 回答