MemoryStream from bytes array with different types of data

亡梦爱人 提交于 2019-12-23 16:34:06

问题


I want to create a memory stream which contains int32, int16, single values. Using binarywriter is useless so i tried to make bytes array. Because values are in different types, I don't know how to do it properly. So I try do like that:

byte[] tab = new byte[]{2,0,0,0,3,0,3,0} - 2 is int32 (four bytes), another two 3 are int16 (two bytes)

that works fine, but when i want to add some single values, it generates errors. I cant do like that :

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

I must have stream in proper format, cause that stream will be read in this method :

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];
        }

Anybody has idea how to do that ??


回答1:


Contrary to your original statement, BinaryWriter is exactly what you want. That's what it's designed for. In particular, it's exactly appropriate if you're going to use BinaryReader later.

You haven't stated why you don't want to use it, but it really is what you should use:

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();
}

This produces a byte array with the following data:

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

One point to note - your writing description writes these values:

- Int32
- Int16
- Int16
- Single
- Single

... but your reading code will read:

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

In other words, if your previous attempts with BinaryWriter were failing because they looked like my initial code, it's because you forgot a

writer.Write(2);

after writing the Int16 values, to say how many Single values were present.

Note that if you don't need the values as a byte array, you don't need to call ToArray - just return the stream (without disposing of it). However, you'll want to "rewind" it before reading it. For example:

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:


A BinaryWriter isn't useless at all. Just create a memorystream and write to it:

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();

Note that I added a count for the float values also. It's not in your example data, but the method that reads the data needs it.

I verified that the data can be read properly. I used your reader code, and wrote out the result:

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

Output:

2
3
3
2
4,4
5,6



回答3:


Constructing a byte array like this doesn't work, because the Int32 and Int16 will be implicitly converted to byte, which doesn't happen for the floating point numbers, hence your compiler error.

The best way is to write to the stream in the same manner you read from it using, BinaryWriter (See the other answers)



来源:https://stackoverflow.com/questions/4966595/memorystream-from-bytes-array-with-different-types-of-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!