C# 来自具有不同数据类型的字节数组的MemoryStream

C# 来自具有不同数据类型的字节数组的MemoryStream,c#,floating-point,byte,memorystream,C#,Floating Point,Byte,Memorystream,我想创建一个包含int32、int16、单个值的内存流。使用binarywriter是无用的,所以我尝试创建字节数组。由于值的类型不同,我不知道如何正确地执行。所以我试着这样做: byte[]tab=新字节[]{2,0,0,3,0,3,0}-2是int32(四个字节),另外两个3是int16(两个字节) 这很好,但是当我想添加一些单个值时,它会产生错误。我不能那样做: byte[]tab=新字节[]{2,0,0,3,0,3,0,4.4f,5.6f} 我必须使流具有正确的格式,因为该流将通过以下方

我想创建一个包含int32、int16、单个值的内存流。使用binarywriter是无用的,所以我尝试创建字节数组。由于值的类型不同,我不知道如何正确地执行。所以我试着这样做:

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

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

byte[]tab=新字节[]{2,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];
        }
short[]原始数据;
浮动[]模块数据;
公共数据流(s)
{
BinaryReader br=新的BinaryReader;
int dataCount=br.ReadInt32();
如果(数据计数>0)
{
rawData=新的短[数据计数];
对于(int i=0;i0)
{
ModuleUSData=新浮点数[数据计数];
对于(int i=0;i

任何人都知道如何做到这一点???

与您最初的陈述相反,
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值之后,说明存在多少个单个值

请注意,如果不需要将值作为字节数组,则不需要调用
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;
}

二进制编写器并非毫无用处。只需创建一个memorystream并写入:

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

像这样构造字节数组是行不通的,因为
Int32
Int16
将被隐式转换为
byte
,这对于浮点数是不会发生的,因此编译器会出错


最好的方法是以与使用BinaryWriter(参见其他答案)读取流相同的方式写入流。更重要的是,这应该做什么?你有这种格式的规格吗?目前,您正在从流中读取一些数字,并使用这些信息来提升读者并选择下一步阅读的内容。看起来您的数据对于该格式根本无效(前提是rawData方法实际执行了它应该执行的操作)。