0
votes

I'm trying to read a binary file, using memorystream and filestream and a struct, with the code below:

BinaryFormatter formatter = new BinaryFormatter();
MemoryStream mStream = new MemoryStream();
byte[] buffer = null;
long numBytes = new FileInfo(filename1).Length;
FileStream fs = new FileStream(filename1, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
buffer = br.ReadBytes((int)numBytes);
mStream.Write(buffer, 0, buffer.Length);
mStream.Position = 0;
GameSaved newdata = (GameSaved)formatter.Deserialize(mStream);
mStream.Close();
fs.Close();
fs.Dispose();
mStream.Dispose();

The GameSaved struct looks like this:

[Serializable]
struct GameSaved
{
    public int Num_Of_Saved_Game;
    public string[] Name_Of_Saved_Game;
}

But the code throws an error

System.InvalidCastException: 'Specified cast is not valid.'

Edit: This is how I save my GameSaved struct:

buffer = null;
formatter = new BinaryFormatter();
mStream = new MemoryStream();
formatter.Serialize(mStream, newdata);
buffer = mStream.ToArray();
mStream.Close();
filename = "name.sav";
curFile = @"c:\C#\Try_To_Save_MS\Try_To_Save_MS\bin\Debug\name.sav";

if (File.Exists(curFile))
    File.Delete(curFile);

fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
fs.Write(buffer, 0, (int)buffer.Length);
fs.Dispose();
mStream.Dispose();

Could anyone please show me the way to solve the problems?

Best Regards

1
what line is throwing exception? GameSaved newdata = (GameSaved)? - TheVillageIdiot
It's the line "GameSaved newdata = (GameSaved)formatter.Deserialize(mStream);" - England Germany
Probably something is broken in the part where you Serialize the GameSaved instance. Could you add that code also? - Steve
And please start using using(). All those .Close()/.Dispose() are making me extremely worried about rest of your application. - Tanveer Badar
It is a pretty standard mishap when you use BinaryFormatter. It is pretty smart and knows exactly which GameSaved declaration was used. Not just its namespace name and type name and what members it has, also what assembly it came from. Kaboom when you don't use the exact same assembly when you read it back. So one basic mistake you could make is re-declaring the struct. Realistically you have to put it in a class library that you use both in the code that writes the file as well as the code that reads it. - Hans Passant

1 Answers

1
votes

You should use the BinaryFormatter.Serialize method to serialize your object. In your code you write a buffer but probably this don't do the same thing

A sample of serialization of your data could written in this way

GameSaved reloaded = new GameSaved();
void Main()
{
    GameSaved game = new GameSaved();
    game.Num_Of_Saved_Game = 2;
    game.Name_Of_Saved_Game = new string[] {"game1", "game2"};

    Serialize(@"e:\temp\serialize.bin", game);
    Deserialize(@"e:\temp\serialize.bin");

    Console.WriteLine("Games:" + reloaded.Num_Of_Saved_Game);
    foreach(string s in reloaded.Name_Of_Saved_Game)
        Console.WriteLine(s);
}

void Deserialize(string filename1)
{
    BinaryFormatter formatter = new BinaryFormatter();
    using(FileStream fs = new FileStream(filename1, FileMode.Open, FileAccess.Read))
        reloaded = (GameSaved)formatter.Deserialize(fs);
}
void Serialize(string filename1, GameSaved game)
{
    BinaryFormatter formatter = new BinaryFormatter();
    using (FileStream fs = new FileStream(filename1, FileMode.OpenOrCreate, FileAccess.Write))
        formatter.Serialize(fs, game);

}
[Serializable]
struct GameSaved
{
    public int Num_Of_Saved_Game;
    public string[] Name_Of_Saved_Game;
}