7

1250バイトの長さの固定長バイト配列があります。次のタイプのデータが含まれる場合があります。

  • 5バイトで構成されるオブジェクトA。最初のバイトには文字「A」が含まれ、次の4バイトには1から100000までの整数が格納されます。

  • 2バイトで構成されるオブジェクトB。最初のバイトには文字「B」が含まれ、次のバイトには1〜100の整数が含まれます。

  • 50バイトで構成されるオブジェクトC。50バイトはすべて、数字と次の文字のみで構成されるASCIIエンコード文字列を格納するために使用されます。- +(および)

バイト配列に各オブジェクトタイプがいくつあるかはわかりませんが、それらがグループ化されていることは知っています(オブジェクトB、オブジェクトB、オブジェクトA、オブジェクトA、オブジェクトA、オブジェクトCなど)。ほとんどの場合、バイト配列を解析すると、配列には1つのタイプのデータが含まれます(たとえば、すべてのアイテムはオブジェクトAです)。したがって、各アイテムが何バイトで構成されているかを正確に把握し、配列をループしてバイトを処理します。 。この場合、すべて異なる長さの3つの異なるタイプのデータがあります。私は次のようなことをする必要があると思っていました:

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 に答える