[.net] Simple question about unserializing an array of floats

Started by
7 comments, last by rikibee 16 years, 4 months ago
I'm doing some experiments with the Tao framework to use OpenGL with C#. Yet my problem is not related directly to OpenGL, it's just that doing OpenGL is one of the situation I came to meet this problem. I have a model file which contains vertex data, index data, texcoords, and so on. Now I made a simple class which reads this file and returns the data that is associated with a particular section of the file. For example, if I ask the FileReader to look for the vertices section, the class returns an array of bytes containing the whole piece of vertex data. Now I got some generic byte[] array. I want to be able to convert that array into the actual data. For vertices, this will be an array of floats. Is there a very casting-like operation I could do in order to get a float[] object from a byte[] object? My guess is that C# is so strongly typed that such operation is not allowed, but I am not sure. I know one solution that would be using the BitConverter class, but will I need to iterate through the byte array and convert them to floats one-by-one? Thanks.
Advertisement
byte[] -> MemoryStream -> BinaryReader -> loop { ReadSingle(); } -> float[]

or, if you're actually starting with a Stream of any kind, skip straight to the BinaryReader.
Thanks,

As you suggest, I will try to go straight from the FileStream to get the floats using ReadSingle() of BinaryReader.

However, must I understand that there are no mechanism that exists in .NET that would allow me to read a block of floats in one call from binary data? I would have liked to have a method that does that the same thing as BinaryReader.ReadBytes but for floats.


Why don't you just use the serialize functions built into .Net?

theTroll
Quote:Original post by TheTroll
Why don't you just use the serialize functions built into .Net?


That sounds good, but I don't want to have the file format depend on the way .NET does its serialization on objects.

.NET serialization would be an obvious choice if I had to save a model to a file and load it back within the same class. But I don't have (i.e. don't want to have) control over the file format, I just want to load chunks of data from an already-defined file format.

Thanks for your help.
You do realize you can use the ISerialisable interface and read and write in pretty much any format you want, right?

theTroll
I am sorry, I don't get it.
But I'll go read the doc on serialization, thanks for the tip.
Probably the best option is to just use a BinaryReader.ReadSingle when loading the file format, and just loop over how many you need to read.

If you have a lot of data to read and this is performance-critical code, then you might try reading it into a byte[] and then use Marshal.AllocHGlobal to allocate a temporary block of unmanaged memory, Marshal.Copy to copy data from the byte[] to the unmanaged memory and then back to a float[] (then use Marshal.FreeHGlobal to free the unmanaged memory).

Another option is to use unsafe code to get a pointer to the byte array and use Marshal.Copy to copy it into the float array. That's one less copy, but it involves using unsafe code, which may or may not perform better.

I'd strongly recommend using the first option until you are sure that it's a performance bottleneck (through profiling), then try something more complicated.

Quote:You do realize you can use the ISerialisable interface and read and write in pretty much any format you want, right?


Implementing ISerializable allows you to control which / how the internal data of a class is serialized, but it's the formatter that really produces the byte stream. For instance, the BinaryFormatter stores a great deal of extra information about types in the file, and its file format allows for multiple reference to a single object, so that when things are deserialized objects aren't unnecessarily duplicated.

If you want to use the .NET serialization to do this, you'd have to write your own Formatter (implementing IFormatter) in addition to implementing ISerializable on the objects that represent the data. If you don't have control over the file format, and especially if you are only deserializing (like if you are reading md2 or bsp files or something), then I'd imagine this route would end up taking a lot more time and coding effort.
I decided to use the ReadSingle in a loop as some of you have suggested.

I appreciated the extra info, kanato. I will follow your advice to make it simple and test if it works for me.

regards

This topic is closed to new replies.

Advertisement