简体   繁体   English

C#文件序列化错误

[英]C# File serialization error

Good day all 大家好

I am trying to teach myself how to do C# file serialization again after not looking at it for year. 在一年不看书之后,我试图教自己如何再次进行C#文件序列化。 I seem to have an error in my code, but cannot seem to fix it or grasp the problem. 我的代码中似乎有一个错误,但似乎无法修复或解决问题。 It has to do with deserializing the objects and reading it into an array. 它与反序列化对象并将其读入数组有关。

Here is my code: 这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Serializing_Files
{
    [Serializable]
    public class Dog
    {
        public string Name { get; set; }
        public string Breed { get; set; }
        public int Age { get; set; }
        public bool IsFemale { get; set; }

        public Dog(string Name, string Breed, int Age, bool IsFemale)
        {
            this.Name = Name;
            this.Breed = Breed;
            this.Age = Age;
            this.IsFemale = IsFemale;
        }

        public override string ToString()
        {
            string dogInfo;

            dogInfo = "Name: "+this.Name;
            return dogInfo;
        }
    }

    public static class DogsFile
    {
        public static BinaryFormatter BFormatter { get; set; }
        public static FileStream FStream { get; set; }
        public static void WriteDog(string FileName, Dog NewDog)
        {
            FStream = new FileStream(FileName, FileMode.Append, FileAccess.Write);
            BFormatter = new BinaryFormatter();
            BFormatter.Serialize(FStream, NewDog);
            Console.WriteLine("{0} has been written to the file.", NewDog.Name);
            FStream.Close();
        }

        public static Dog[] ReadDogs(string FileName)
        {
            FStream = new FileStream(FileName, FileMode.Open, FileAccess.Read);
            BFormatter = new BinaryFormatter();

            Dog[] DogArray = new Dog[FStream.Length];
            int i = 0;

            while (FStream.Position < FStream.Length)
            {
                DogArray[i] = (Dog)BFormatter.Deserialize(FStream); //line where error occurs
                Console.WriteLine("The file contans the following Dogs:");
                Console.WriteLine(DogArray[i].ToString());

                i++;
            }
            FStream.Close();
            return DogArray;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string filename = @"C:\Dogfile.ser";
            Dog[] allDogs = new Dog[3];

            allDogs[0] = new Serializing_Files.Dog("Scruffy", "Maltese", 3, true);
            DogsFile.WriteDog(filename, allDogs[0]);

            allDogs[1] = new Serializing_Files.Dog("Butch", "Bulldog", 1, false);
            DogsFile.WriteDog(filename, allDogs[1]);

            allDogs[2] = new Serializing_Files.Dog("Balo", "Chow Chow", 1, false);
            DogsFile.WriteDog(filename, allDogs[2]);

            DogsFile.ReadDogs(filename);
            Console.ReadLine();
        }
    }
}

I am receiving the following runtime error in line 60: 我在第60行收到以下运行时错误:

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll mscorlib.dll中发生了类型为'System.Runtime.Serialization.SerializationException'的未处理异常

Additional information: The input stream is not a valid binary format. 附加信息:输入流不是有效的二进制格式。 The starting contents (in bytes) are: 0B-5F-5F-42-61-63-6B-69-6E-67-46-69-65-6C-64-01-01 ... 起始内容(以字节为单位)为:0B-5F-5F-42-61-63-6B-69-6E-67-46-69-65-6C-64-01-01 ...

I wrote this file using a combination of several tutorials, so I might have misunderstood something. 我使用多个教程的组合编写了此文件,因此我可能会误解了一些东西。 Could someone please help me understand what I am doing wrong? 有人可以帮我了解我在做什么错吗? I would be extremely grateful for any advice you might be able to offer. 我将非常感谢您可能提供的任何建议。

A follow up question: I am using "FileMode.Append" when adding to the file. 后续问题:添加到文件时,我正在使用“ FileMode.Append”。 How would I make sure that the file exists in the first place? 我如何确保文件首先存在? Should I run a line of code at the start using "FileMode.Create" separately, or is there a better practice approach that I could use? 我应该一开始使用“ FileMode.Create”单独运行一行代码,还是可以使用更好的实践方法?

Many thanks in advance! 提前谢谢了!

Your code does not crash. 您的代码不会崩溃。 Probably you created file with different objects (Maybe you added some properties afterwards) and now it cannot deserialize. 可能是您创建了具有不同对象的文件(也许之后添加了一些属性),现在它无法反序列化。 Remove your file and launch your program again. 删除文件,然后再次启动程序。 File mode works fine. 文件模式工作正常。 No need to change. 无需更改。

Another point is to serialize collection instead of writing objects one by one. 另一点是序列化集合,而不是一个一个地写对象。

public static class DogsFile
{
    public static BinaryFormatter BFormatter { get; set; }
    public static FileStream FStream { get; set; }
    public static void WriteDog(string FileName, Dog[] NewDog)
    {
        FStream = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write);
        BFormatter = new BinaryFormatter();
        BFormatter.Serialize(FStream, NewDog);
        FStream.Close();
    }

    public static Dog[] ReadDogs(string FileName)
    {
        FStream = new FileStream(FileName, FileMode.Open, FileAccess.Read);
        BFormatter = new BinaryFormatter();
        var DogArray = (Dog[])BFormatter.Deserialize(FStream);
        FStream.Close();
        return DogArray;
    }
}

After some helpful suggestions from @Access Denied and @ZRT, here is the working code. 在@Access Denied和@ZRT提出了一些有用的建议之后,这里是工作代码。 Thanks guys! 多谢你们!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Serializing_Files
{
    [Serializable]
    public class Dog
    {
        public string Name { get; set; }
        public string Breed { get; set; }
        public int Age { get; set; }
        public bool IsFemale { get; set; }

        public Dog(string Name, string Breed, int Age, bool IsFemale)
        {
            this.Name = Name;
            this.Breed = Breed;
            this.Age = Age;
            this.IsFemale = IsFemale;
        }

        public override string ToString()
        {
            string dogInfo;

            dogInfo = "Name: " + this.Name + Environment.NewLine + "Breed: " + this.Breed + Environment.NewLine + "Age: " + this.Age + Environment.NewLine;
            if (this.IsFemale)
            {
                dogInfo += "Gender: Female";
            }
            else
            {
                dogInfo += "Gender: Male";
            }
            dogInfo += Environment.NewLine;

            return dogInfo;
        }
    }

    public static class DogsFile
    {
        public static BinaryFormatter BFormatter { get; set; }
        public static FileStream FStream { get; set; }
        public static void WriteDog(string FileName, Dog[] NewDogs)
        {
            FStream = new FileStream(FileName, FileMode.Create, FileAccess.Write);
            BFormatter = new BinaryFormatter();
            BFormatter.Serialize(FStream, NewDogs);

            Console.WriteLine("The following dogs were written to the file:" + Environment.NewLine);

            for (int i = 0; i < NewDogs.Length; i++)
            {
                Console.WriteLine(NewDogs[i].ToString());
            }

            Console.WriteLine(Environment.NewLine);

            FStream.Close();
        }

        public static Dog[] ReadDogs(string FileName)
        {
            FStream = new FileStream(FileName, FileMode.Open, FileAccess.Read);
            BFormatter = new BinaryFormatter();
            var DogArray = (Dog[])BFormatter.Deserialize(FStream);

            Console.WriteLine("The file contains the following dogs:"+Environment.NewLine);

            for (int i = 0; i < DogArray.Length; i++)
            {
                Console.WriteLine(DogArray[i].ToString());
            }

            FStream.Close();
            return DogArray;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string filename = @"C:\Dogfile1.ser";
            Dog[] allDogs = new Dog[3];

            allDogs[0] = new Dog("Scruffy", "Maltese", 3, true);

            allDogs[1] = new Dog("Butch", "Bulldog", 1, false);

            allDogs[2] = new Dog("Balo", "Chow Chow", 1, false);

            DogsFile.WriteDog(filename, allDogs);

            DogsFile.ReadDogs(filename);

            Console.ReadLine();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM