C # Ошибка сериализации файла - PullRequest
0 голосов
/ 29 августа 2018

Добрый день всем

Я пытаюсь научить себя, как выполнить сериализацию файла C # после того, как год не смотрел Кажется, в моем коде есть ошибка, но я не могу ее исправить или понять проблему. Это связано с десериализацией объектов и чтением их в массив.

Вот мой код:

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();
        }
    }
}

Я получаю следующую ошибку во время выполнения в строке 60:

Необработанное исключение типа «System.Runtime.Serialization.SerializationException» произошло в mscorlib.dll

Дополнительная информация: входной поток не является допустимым двоичным форматом. Начальное содержимое (в байтах): 0B-5F-5F-42-61-63-6B-69-6E-67-46-69-65-6C-64-01-01 ...

Я написал этот файл, используя комбинацию из нескольких руководств, так что я мог что-то неправильно понять. Может ли кто-нибудь помочь мне понять, что я делаю неправильно? Я был бы чрезвычайно признателен за любой совет, который вы могли бы предложить.

Следующий вопрос: я использую «FileMode.Append» при добавлении в файл. Как бы я убедиться, что файл существует в первую очередь? Должен ли я запустить строку кода в начале, используя «FileMode.Create» отдельно, или есть лучший практический подход, который я мог бы использовать?

Заранее большое спасибо!

Ответы [ 3 ]

0 голосов
/ 29 августа 2018
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;
    }
}
0 голосов
/ 29 августа 2018

После некоторых полезных советов от @Access Denied и @ Z.R.T, вот рабочий код. Спасибо, ребята!

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();
        }
    }
}
0 голосов
/ 29 августа 2018

Ваш код не падает. Возможно, вы создали файл с другими объектами (возможно, вы добавили некоторые свойства впоследствии), и теперь он не может десериализоваться. Удалите файл и снова запустите программу. Файловый режим работает отлично. Не нужно менять.

Другой момент - сериализация коллекции вместо записи объектов один за другим.

...