John Smith
John Smith

Reputation: 97

SerializationException: 'Attempting to deserialize an empty stream.' The file I am trying to deserialize has content. What is happening?

Summary


I've been given a brief to create a software solution that has persistence. However, I have found errors with my serialization that don't make sense, as the object I am trying to deserialize has content and is not empty. I've spent approximately 3 hours screwing around with different versions, as well as information from the internet, without success. Sorry for the large chunks of code, but I can't find where it's failing.

Resources


BinaryFormatter & CryptoStream problem when deserializing

Attempting to deserialize an empty stream?

Runtime error Attempting to deserialize an empty stream

Microsoft Documentation - ISerializable

SerializableAttribute

Code


Deserialization

string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\')[1];
            string folderName = "c:\\Users\\"+ userName + "\\Documents";
            string pathString = System.IO.Path.Combine(folderName, "Clients");
            System.IO.Directory.CreateDirectory(pathString);
            string[] FileNames = Directory.GetFiles("C:\\Users\\" + userName + "\\Documents\\Clients\\", "*.clnt")
                .Select(System.IO.Path.GetFileName)
                .ToArray();
            if (FileNames.Length > 0)
            {
                for (int Count = 0; Count <= FileNames.Length; ++Count)
                {

                    FileStream s = new FileStream(FileNames[Count] + ".clnt", FileMode.Open, FileAccess.Read);
                    IFormatter formatter = new BinaryFormatter();
                    ClientDataClass Client = (ClientDataClass)formatter.Deserialize(s);
                    s.Close();
                    ClientComboChoice.Items.Add(Client);
                }
            }

        }

Serialization

protected ClientDataClass(SerializationInfo info, StreamingContext context )
{
    StClientBrief = info.GetString(StClientBrief);
    StClientName = info.GetString(StClientName);
    StClientEmail = info.GetString(StClientEmail);
    StartDate = info.GetDateTime(StartDate.ToString());
    DueDate = info.GetDateTime(DueDate.ToString());
    Price = info.GetDouble(Price.ToString());
    SFW = info.GetBoolean(SFW.ToString());
    Planning = info.GetBoolean(Planning.ToString());
    PlanName = info.GetString(PlanName);
}

//[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] Learnt this is obsolete 25/02/2019
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    info.AddValue("ClientName", StClientName);
    info.AddValue("ClientBrief", StClientBrief);
    info.AddValue("ClientEmail", StClientEmail);
    info.AddValue("StartDate", StartDate);
    info.AddValue("DueDate", DueDate);
    info.AddValue("Price", Price);
    info.AddValue("SFW", SFW);
    info.AddValue("Planning", Planning);
    info.AddValue("Plan Name", PlanName);

}

}

Proof File has Contents


Proof it has contents

Proof it exists

Attempts


I have tried changing the extension (It matches the file). I've tried removing the extension. I've tried changing the serialization part of the data class.

Question


What's wrong? How do I avoid it in future? How do I fix it?

Upvotes: 0

Views: 784

Answers (1)

Samuel
Samuel

Reputation: 81

Since I can't put this in the comments:
It looks like you are trying to do too much. I would start out by breaking down the steps and make sure you have everything you need before trying to read the files.

My guess is you are passing the file name into this, but you really need to pass in the whole path to the file.

Try this.

string[] FileNames = Directory.GetFiles("C:\\Users\\" + userName + "\\Documents\\Clients\\", "*.clnt");
        foreach(string file in FileNames)
{
   FileStream s = new FileStream(file, FileMode.Open, FileAccess.Read);
   IFormatter formatter = new BinaryFormatter();
   ClientDataClass Client = (ClientDataClass)formatter.Deserialize(s);
   s.Close();
   ClientComboChoice.Items.Add(Client);
}

You can check the filenames by doing

foreach(string file in FileNames)
{
   Console.WriteLine(file);
   //FileStream s = new FileStream(file, FileMode.Open, FileAccess.Read);
   //IFormatter formatter = new BinaryFormatter();
   //ClientDataClass Client = (ClientDataClass)formatter.Deserialize(s);
   //s.Close();
   //ClientComboChoice.Items.Add(Client);
}

If you can open the file, then I think you are good to go, not certain about the serialize/deserialize operations, but it looks ok.

Upvotes: 1

Related Questions