Komm
Komm

Reputation: 351

Understanding saving - do I only use Stream, or use both Formatter and Stream?

From what I understand, the Formatter converts a serializable object into a stream of bytes and the Stream (e.g. FileStream) does the actual writing of those bytes into a file. Example code:

public static void SaveData(MySerializableData data)
{
    BinaryFormatter formatter = new BinaryFormatter();
    FileStream stream = new FileStream(SavePath, FileMode.Create);        
    formatter.Serialize(stream, data);
    stream.Close();
}

However at other times, I'm also seeing this type of code:

void Save()
{
    string data = "Value 1";
    StreamWriter writer = new StreamWriter("MySaveFile.txt", true);
    writer.Write(data);
}

Why is it that in the second case, we abandon the 2-step process of saving? Why do we sometimes use only StreamWriter, but at other times use both the formatter and a stream object?

Thank you!

Upvotes: 0

Views: 74

Answers (1)

Gusman
Gusman

Reputation: 15161

BinaryFormatter serializes a class into a byte array and writes it to a stream. It's useful when you want to save/load classes with it's data. Serializtion stores metadata about the class graph that is storing.

StreamWriter is a stream that has specific functions to write a string into a file.

Consider this example:

MemoryStream mstr = new MemoryStream();

string datastr = "hello!";

BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(mstr, datastr);
mstr.Seek(0, SeekOrigin.Begin);

string resultString = Encoding.ASCII.GetString(mstr.ToArray());

If you inspect resultString you will find that it contains something like this:

"\0\u0001\0\0\0????\u0001\0\0\0\0\0\0\0\u0006\u0001\0\0\0\u0006hello!\v"

Well, that's not what you would want to have in a text file, right? As you see serialization is not intended to store raw data but class instances.

Now check this:

MemoryStream mstr = new MemoryStream();
StreamWriter sw = new StreamWriter(mstr);
string datastr = "hello!";
sw.Write(datastr);
mstr.Seek(0, SeekOrigin.Begin);
sw.Close();

string resultString = Encoding.ASCII.GetString(mstr.ToArray());

If you now inspect resultString it will contain:

"hello!"

As you see it's very different, that's what you would expect in a text file.

You can also store raw binary data with a stream:

byte[] data = new byte[]{ 1,2,3,4 };
var fs = File.Create("out.dat"); //this creates a new file and creates a filestream
fs.Write(data, 0, data.Length);
fs.Close();

If you now inspect the file with a binary editor you will see it contains:

0x01, 0x02, 0x03, 0x04

There are many types of streams with different purposes (per example, the MemoryStream that I used in the examples, a binary stream that stores it's data into an array in memory) and a ton of classes that use streams for many things, in this case you have mixed the concepts of serialization and data storage using streams, those are two different things.

Upvotes: 1

Related Questions