奇怪的错误:“输入流不是有效的二进制格式”

jst*_*rdo 0 c# serialization deserialization

我有以下代码来序列化和反序列化数据:

    static public void Serialize(List<Access> accesos, Stream stream)
    {
        IFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, accesos);
    }

    static public List<Access> Deserialize(Stream stream)
    {
        try
        {
            IFormatter formatter = new BinaryFormatter();
            List<Access> data = formatter.Deserialize(stream) as List<Access>;
            return data;
        }
        catch
        {
            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题是当我将一个序列化List<>到一个文件,并立即尝试反序列化时,错误

“输入流不是有效的二进制格式”

被抛出formatter.Deserialize(stream)线。

在序列化时,流被打开:

Stream stream = File.Open(GetConfigurationFilePath(), FileMode.Create);
Run Code Online (Sandbox Code Playgroud)

在反序列化时,流被打开:

Stream stream = File.Open(GetConfigurationFilePath(), FileMode.Open);
Run Code Online (Sandbox Code Playgroud)

这里可能会发生什么?二进制格式没有任何改变。

编辑:这就是我调用两个静态方法的方式:

            using (Stream stream = File.Open(GetConfigurationFilePath(), FileMode.Create))
            {
                this.Accesos = frm.Accesos;
                Serializer.Serialize(this.Accesos, stream);
                stream.Close();
            }

            using (Stream stream = File.Open(GetConfigurationFilePath(), FileMode.Open))
            {
                this.Accesos = Serializer.Deserialize(stream);
                stream.Close();
            }

    private string GetConfigurationFilePath()
    {
        string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        if (path.Last() != '\\')
            path += '\\';
        path += CONFIG_FILE;

        return path;
    }
Run Code Online (Sandbox Code Playgroud)

das*_*ght 5

当我将 a 序列化为List<Access>文件时,并立即尝试反序列化...

这里最可能的问题是程序在您开始反序列化文件内容时尚未完成写入流。格式化程序确实完成了它的工作,但部分数据仍缓存在内存中。这可能是因为您的代码没有明确地或通过处置流来关闭文件流。

using在您的流周围添加应该可以解决问题:

using (Stream stream = File.Open(GetConfigurationFilePath(), FileMode.Create)) {
    ... // Serialization code
}
using (Stream stream = File.Open(GetConfigurationFilePath(), FileMode.Open)) {
    ... // Deserialization code
}
Run Code Online (Sandbox Code Playgroud)