我无法修改序列化数据(c#)

时间:2017-04-16 23:00:47

标签: c# serialization

嗯,我的问题是下一个,我必须在c#控制台上制作一个游戏,可以将角色的位置保存在二进制存档中,所以当我重新启动游戏时,角色处于同一位置死了或我关闭游戏。现在,它第一次运行,它使它完美并且存档已经完成,但第二次我必须序列化,它给我一个运行时错误(mscorlib.dll中发生了'System.ArgumentException'类型的未处理异常并且它标志着“不能修改”的安全性。

为什么会发生这种情况?

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

namespace Game
{
    [Serializable]
    struct Position
    {
        public int x;
        public int y;
    }
    class Program
    {
        static void Main(string[] args)
        {

            //FileStream data = new FileStream("gameData.txt", FileMode.OpenOrCreate); //abre el codigo si existe. sino, lo crea.
            //StreamWriter textSaver = new StreamWriter(data); //escritor de texto
            //BinaryWriter scoreSaver = new BinaryWriter(data);
            //BinaryFormatter formatter = new BinaryFormatter();
            //FileStream playerPosData = new FileStream("PlayerPosData.txt", FileMode.OpenOrCreate);
            Position where;
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream playerPosData;
            if (!File.Exists("PlayerPosData.txt"))
            {
                playerPosData = File.Create("PlayerPosData.txt");
                where.x = 50;
                where.y = 20;
            }
            else
            {
                playerPosData = File.OpenRead("PlayerPosData.txt");
                where = (Position)formatter.Deserialize(playerPosData);
            }
            Menu theMenu = new Menu();
            if(theMenu.MoveAndChoose() == true)
            {
                Score theScore = new Game.Score();
                Console.BackgroundColor = ConsoleColor.Green;
                Console.ForegroundColor = ConsoleColor.Red;
                Random rand = new Random();
                Player zero = new Player(where.x, where.y);
                Enemy[] badGuys = new Enemy[20];
                for (int i = 0; i < badGuys.Length; i++)
                    badGuys[i] = new Enemy(rand.Next(0, 79), rand.Next(0, 23));
                Bomb[] mines = new Bomb[5];
                for (int i = 0; i < mines.Length; i++)
                    mines[i] = new Bomb(rand.Next(0, 79), rand.Next(0, 23));
                Console.SetCursorPosition(35, 12);
                Console.WriteLine("GAME START!");
                zero.draw();
                Console.ReadKey();
                while (zero.CheckLife() == true)
                {
                    Console.Clear();
                    zero.draw();
                    if (Console.KeyAvailable)
                    {
                        ConsoleKeyInfo controls = Console.ReadKey();
                        zero.Moverse(controls);
                    }

                 for (int i = 0; i < mines.Length; i++)
                    { 
                        mines[i].Draw();
                        if (mines[i].Sense(zero.getX(), zero.getY()))
                            zero.death();
                    }
                    for (int i = 0; i < badGuys.Length; i++)
                    {
                        badGuys[i].draw();
                        badGuys[i].Move();
                        if (badGuys[i].searchAndKill(zero.getX(), zero.getY()))
                            zero.death();
                    }
                    theScore.scoreUp();
                    if (theScore.getScoreNumber() > theScore.getHighScore())
                        theScore.setHighScore(theScore.getScoreNumber());
                    theScore.Draw();
                    System.Threading.Thread.Sleep(50);
                }
                Console.SetCursorPosition(35, 12);
                Console.WriteLine("GAME OVER");
                //textSaver.WriteLine("Acá va a ir el highscore. Testeando"); //Test de puntuacion
                //scoreSaver.Write(theScore.getHighScore());
                //textSaver.Close();
                //data.Close();
                where.x = zero.getX();
                where.y = zero.getY();
                formatter.Serialize(playerPosData, where); // it stops here and says "it can't be modified" the second time
                playerPosData.Close();
                Console.ReadKey();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果文件存在,&#34; playerPosData&#34;将是

playerPosData = File.OpenRead("PlayerPosData.txt");

问题是,您只打开一个流作为READ。如果你写了一些文本,那么它会给出错误,因为你只能读取流。

请查看以下代码以获取可能的解决方案:

 Position where;
        BinaryFormatter formatter = new BinaryFormatter();

        if (!File.Exists("PlayerPosData.txt"))
        {
            File.Create("PlayerPosData.txt");
            where.x = 50;
            where.y = 20;
        }
        else
        {
            using (var playerPosData = File.OpenRead("PlayerPosData.txt"))
            {
                where = (Position)formatter.Deserialize(playerPosData);
            }
        }

        // ...

        using (var playerPosData = File.OpenWrite("PlayerPosData.txt"))
        {
            formatter.Serialize(playerPosData, where); // it stops here and says "it can't be modified" the second time
        }

            Console.ReadKey();

使用块完成后,使用可帮助您关闭流。它会自动调用流的dispose方法。