在多个应用程序中加载序列化数据C#

时间:2015-07-30 11:15:06

标签: c# serialization binaryfiles binary-data

方案: 我有一个程序,它使用一个简单的类来生成游戏数据。使用所述程序,我使用序列化和BinaryFormatter将数据写入要由第二个程序使用的文件。从这个初始程序中读取数据没有问题。

问题: 这可能取决于我对序列化文件的处理方式的无知,但我无法将这些数据加载到第二个程序中,即实际的游戏本身。

saveGame代码(在程序1中):

DataSource

loadGameData :(在程序2中)

static List<GameData> gameData;
static GameData currentData;

private void saveGame(Sudoku sdk) {
    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = null;
    try {
        if(!File.Exists(gameDataFile[currentDifficulty])) {
            file = File.Open(gameDataFile[currentDifficulty], FileMode.CreateNew);
        } else {
            file = File.Open(gameDataFile[currentDifficulty], FileMode.Append);
        }
        currentData = setGameData(sdk);
        bf.Serialize(file, currentData);
        savePuzzleLog();
    } catch(Exception e) {
        Debug.LogException("saveGame", e);
    }
    if(file != null) {
        file.Close();
    }
}

GameData类:(第一个程序)

public static List<GameData> gameData;

public bool loadGameData() {
    if(gameData == null) {
        gameData = new List<GameData>();
    } else {
        gameData.Clear();
    }
    bool loadData = true;
    bool OK = false;
    if(File.Exists(gameDataFile[currentDifficulty])) {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Open(gameDataFile[currentDifficulty], FileMode.Open);
        while(loadData) {
            try {
                GameData gd = new GameData();
                gd = (GameData)bf.Deserialize(file);
                gameData.Add(gd);
                OK = true;
                if(file.Position == file.Length) {
                    loadData = false;
                }
            } catch(Exception e) {
                Debug.LogException(e);
                loadData = false;
                OK = false;
            }
        }
        if(file != null) {
            file.Close();
        }
    } else {
        Debug.LogWarning(gameDataFile[currentDifficulty] + " does not exist!");
    }
    return OK;
}

GameData类:(第二个程序)唯一的区别是声明为公共

[Serializable]
class GameData {
    private int gameID;
    private List<int> contentArray;
    private int difficultyValue;

    public GameData(List<int> data = null) {
        id = -1;
        difficulty = -1;
        if(content != null) {
            content.Clear();
        } else {
            content = new List<int>();
        }
        if(data != null) {
            foreach(int i in data) {
                content.Add(i);
            }
        }
    }

    public int id {
        get {
            return this.gameID;
        }
        set {
            this.gameID = value;
        }
    }

    public int difficulty {
        get {
            return this.difficultyValue;
        }
        set {
            this.difficultyValue = value;
        }
    }

    public List<int> content {
        get {
            return this.contentArray;
        }
        set {
            this.contentArray = value;
        }
    }
}

我的问题是,如何在一个程序中保存数据并能够使用不同的程序加载它而不会出现序列化错误,或者我是否需要使用备用保存/加载方法和/或类结构?

2 个答案:

答案 0 :(得分:1)

当我必须这样做的时候,我这样做了:

一个独立的dll(程序集),包含保存数据的类(适用于GameData类),以及用于保存/加载文件的实用程序方法。

您的另外两个项目必须引用此dll(程序集),您应该能够(de)正确序列化。

我认为问题在于你的情况是BinaryFormatter不仅保存文件中的数据,还保存序列化对象的完整类型。

当您尝试在另一个类似对象中反序列化时,即使结构相同,该类的全名也不会(因为程序集名称不是)。

答案 1 :(得分:1)

好的,我已经根据给出的建议对其进行了分类。我没有使用BinaryFormatter,而是使用了BinaryWriter和BinaryReader,如下所示......

在程序1(创建者)中:

#!/usr/bin/env perl
use strict;
do 'nap.pl';

&nap;
print `ls /tmp/`;
sleep 5;

在计划2中:(实际游戏)

    private byte[] setByteData(Sudoku sdk) {
        List<int> clues = sdk.puzzleListData();
        byte[] bd = new byte[puzzleSize];
        SudokuSolver solver = new SudokuSolver();
        List<int> solution = solver.Solve(sdk.Copy(), false, currentDifficulty).puzzleListData();
        for(int i = 0; i < puzzleSize; i++) {
            bd[i] = Convert.ToByte(solution[i] + (clues[i] == 0 ? 0xF0 : 0));
        }
        return bd;
    }

    private GameData setGameData(Sudoku sdk) {
        List<int> clues = sdk.puzzleListData();
        GameData gd = new GameData();
        gd.id = puzzleList.Items.Count;
        gd.difficulty = currentDifficulty;
        SudokuSolver solver = new SudokuSolver();
        List<int> solution = solver.Solve(sdk.Copy(), false, currentDifficulty).puzzleListData();
        for(int i = 0; i < puzzleSize; i++) {
            gd.content.Add(solution[i] + (clues[i] == 0 ? 0xF0 : 0));
        }
        return gd;
    }

    private List<int> getByteData(byte[] data) {
        List<int> retVal = new List<int>();
        foreach(byte i in data) {
            if(i > 9) {
                retVal.Add(i - 0xF0);
            } else {
                retVal.Add(0);
            }
        }
        return retVal;
    }

    private string getGameData(List<int> data) {
        string retVal = "";
        foreach(int i in data) {
            if(i > 9) {
                retVal += (i - 0xF0).ToString();
            } else {
                retVal += i.ToString();
            }
        }
        return retVal;
    }

    private void saveGame(Sudoku sdk) {
        FileStream file = null;
        BinaryWriter bw = null;
        try {
            if(!File.Exists(gameDataFile[currentDifficulty])) {
                file = File.Open(gameDataFile[currentDifficulty], FileMode.CreateNew);
            } else {
                file = File.Open(gameDataFile[currentDifficulty], FileMode.Append);
            }
            bw = new BinaryWriter(file);
            currentData = setGameData(sdk);
            byte[] bd = setByteData(sdk);
            bw.Write(currentData.id);
            bw.Write(currentData.difficulty);
            bw.Write(bd);
            savePuzzleLog();
        } catch(Exception e) {
            Debug.LogException("saveGame", e);
        }
        if(file != null) {
            if(bw != null) {
                bw.Flush();
                bw.Close();
            }
            file.Close();
        }
    }

类结构与以前相同,但使用此方法解决了我的问题,我现在可以使用我的创建者创建数据文件,并使用实际游戏轻松加载数据。

感谢大家的帮助和建议,帮助我对此进行排序。