【问题标题】:MemoryStream from bytes array with different types of data来自具有不同类型数据的字节数组的 MemoryStream
【发布时间】:2011-02-11 07:28:38
【问题描述】:

我想创建一个包含 int32、int16、单个值的内存流。使用 binarywriter 是没用的,所以我尝试制作字节数组。因为值的类型不同,所以我不知道如何正确地做到这一点。所以我尝试这样做:

byte[] tab = new byte[]{2,0,0,0,3,0,3,0} - 2 是 int32(四个字节),另外两个 3 是 int16(两个字节)

这很好,但是当我想添加一些单个值时,它会产生错误。我不能那样做:

byte[] tab = new byte[]{2,0,0,0,3,0,3,0,4.4f,5.6f}

我必须有正确格式的流,因为该流将在此方法中被读取:

short[] rawData;
 float[] modulusData;
   public void rawData(Stream s)
        {

            BinaryReader br = new BinaryReader(s);

            int dataCount = br.ReadInt32();

            if (dataCount > 0)
            {
                rawData = new short[dataCount];
                for (int i = 0; i < dataCount; i++)
                    rawData[i] = br.ReadInt16();
            }
            else
                rawData = new short[0];

            dataCount = br.ReadInt32();

            if (dataCount > 0)
            {
                modulusData = new float[dataCount];
                for (int i = 0; i < dataCount; i++)
                    modulusData[i] = br.ReadSingle();
            }
            else
                modulusData = new float[0];
        }

有人知道怎么做吗??

【问题讨论】:

  • 更重要的是 - 这应该做什么?你有格式的规格吗?目前,您正在从流中读取一些数字,并使用该信息来推进阅读器并选择接下来要阅读的内容。看来您的数据对于格式根本无效(前提是 rawData 方法实际上做了它应该做的事情)。

标签: c# floating-point byte memorystream


【解决方案1】:

与您的原始陈述相反,BinaryWriter 正是您想要的。这就是它的设计目的。特别是,如果您以后要使用BinaryReader,则非常合适。

你没有说明你为什么不想使用它,但它确实是你应该使用的:

using (MemoryStream stream = new MemoryStream())
{
    using (BinaryWriter writer = new BinaryWriter(stream))
    {
        writer.Write(2);
        writer.Write((short) 3);
        writer.Write((short) 3);
        writer.Write(4.4f);
        writer.Write(5.6f);
    }
    byte[] bytes = stream.ToArray();
}

这会产生一个包含以下数据的字节数组:

[Int32    ] [Int16] [Int16] [Single   ] [Single   ]
02 00 00 00 03 00   03 00   CD CC 8C 40 33 33 B3 40

需要注意的一点——你的写作描述写了这些值:

- Int32
- Int16
- Int16
- Single
- Single

...但是您的阅读代码将显示为:

- Int32 (value 2)
- Int16
- Int16
- Int32 (this wasn't written - so you're reading data from the first Single!)
- ???

换句话说,如果您之前使用BinaryWriter 的尝试失败是因为它们看起来像我的初始代码,那是因为您忘记了一个

writer.Write(2);

写完 Int16 值后,说明有多少个 Single 值。

请注意,如果您不需要将值作为字节数组,则无需调用 ToArray - 只需返回流(不处理它)。但是,您需要在阅读之前“倒带”它。例如:

public Stream GetData()
{
    MemoryStream stream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(stream); // Don't close at the end!
    writer.Write(2);
    writer.Write((short) 3);
    writer.Write((short) 3);
    writer.Write(2); // Extra count for the Single values
    writer.Write(4.4f);
    writer.Write(5.6f);
    writer.Flush(); // May not be required...

    stream.Position = 0; // Rewind so stream can be read again
    return stream;
}

【讨论】:

    【解决方案2】:

    BinaryWriter 一点也不无用。只需创建一个内存流并写入它:

    MemoryStream m = new MemoryStream();
    using (BinaryWriter writer = new BinaryWriter(m)) {
      writer.Write(2); // count
      writer.Write((short)3);
      writer.Write((short)3);
      writer.Write(2); // count
      writer.Write(4.4f);
      writer.Write(5.6f);
    }
    byte[] tab = m.ToArray();
    

    请注意,我还为浮点值添加了计数。它不在您的示例数据中,但读取数据的方法需要它。

    我验证数据可以正确读取。我使用了你的阅读器代码,并写出了结果:

    Console.WriteLine(rawData.Length);
    foreach (short x in rawData) Console.WriteLine(x);
    Console.WriteLine(modulusData.Length);
    foreach (float f in modulusData) Console.WriteLine(f);
    

    输出:

    2
    3
    3
    2
    4,4
    5,6
    

    【讨论】:

      【解决方案3】:

      像这样构造一个字节数组是行不通的,因为Int32Int16 将被隐式转换为byte,浮点数不会发生这种情况,因此会出现编译器错误。

      最好的方法是以与读取流相同的方式写入流,BinaryWriter(请参阅其他答案)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-30
        • 2014-08-29
        • 2019-07-24
        • 2015-07-10
        • 1970-01-01
        • 2012-11-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多