Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MemoryStream from bytes array with different types of data

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 ??

like image 837
PiterK Avatar asked Nov 19 '25 00:11

PiterK


1 Answers

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;
}
like image 137
Jon Skeet Avatar answered Nov 20 '25 14:11

Jon Skeet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!