根据需要高效存储和加载数据(可能类似于视频游戏资产)

时间:2018-04-07 11:54:30

标签: c# wpf storage protocol-buffers protobuf-net

我正在寻找一种在WPF应用程序中存储和加载大量数据的好方法。我目前正在研究protobuf-net,但可能有更好的方法。

上下文
作为一个有趣的小项目,我正在编写一个程序,帮助我组织我的D& D(龙与地下城)活动的所有内容,其中包括根据我所需的规则变化提供所有可用的源材料和编辑。

我目前正在制作程序中显示游戏中所有法术的部分,并允许对其进行编辑并添加新法术。在D& D中有超过400个法术,不包括我自己可能添加的任何法术。每个法术的大小与this相似。每个咒语(或D& D中的其他对象)将由其自己的代码类表示,以允许搜索,排序和模拟等奇特的东西。除了法术之外,还有许多其他物品将被存储,其中许多物品将相互依赖。例如,每个咒语都有一个DnDItems字段,其中包含投射它所需的项目,其中DnDItem只是另一个将单独存储的D& D特定类。

问题
如果这些数据不仅仅是一个字符串,那么存储和加载它的最佳方法是什么?我使用WPF ListView查看法术列表,所选法术将在侧面的面板中显示详细信息。除此之外,法术将从该计划的许多其他地方链接,因为D& D中的许多东西是相互关联的。我正在考虑protobuf-net,因为我听说过很多很棒的事情。

对我来说最重要的部分是性能,那么什么是最好的解决方案?

编辑:程序及其使用的所有数据目前仅计划在本地提供。

1 个答案:

答案 0 :(得分:1)

对于那些专注于企业级软件的人来说,数据库是显而易见的。 对于可在桌面上运行的应用程序,每个用户只需要自己的数据存储,但它并不总是最好的选择。

我建议您研究序列化和反序列化。这非常快 - 比存储在本地数据库中快得多。 您只需使用公共属性构建类,然后就可以对它们进行序列化。 这是我游戏中的一些代码。

public static void SaveScenario(string fileURL, Scenario scenario)
{
    scenario.ScenarioFile = fileURL;
    using (FileStream writer = new FileStream(fileURL, FileMode.Create))
    {
        DataContractSerializer ser = new DataContractSerializer(typeof(Scenario));
        ser.WriteObject(writer, scenario);
    } 
}
public static Scenario ReadScenario(string fileURL)
{
    FileStream fs = new FileStream(fileURL, FileMode.Open);
    XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
    DataContractSerializer ser = new DataContractSerializer(typeof(Scenario));
    Scenario deserializedScenario = (Scenario)ser.ReadObject(reader, true);
    reader.Close();
    fs.Close();
    return deserializedScenario;
}

读取和写入xml文件。 场景只是一个公共属性的公共类:

public class Scenario
{

    public string ScenarioName { get; set; } = "";
    public string ScenarioDescription { get; set; } = "";
    public string ScenarioFile { get; set; } = "";
    public int NumTurns { get; set; } = 0;

...

    [IgnoreDataMember]
    public bool[,] ValidTerrain = new bool[,]

IgnoreDataMember属性可避免序列化属性。 一些属性是复杂对象的集合。

一旦将文件读入内存,就可以使用linq对象进行搜索,排序等等。 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/linq-to-objects

如果您想要缩小尺寸或存储多个文件,也可以将其与压缩文件结合使用。 400法术不是很多数据。

我不知道组件有多少重叠,但让我们想象一下像组件这样的东西被多次使用。你可以在你的法术课中拥有一个组件集合属性,而你不想多次重复使用eyet of newt。您可以使用ID来处理。所以你存储一个组件列表,每个组件都有一个int id。然后,一个咒语中的组件列表可以只有ComponentId,并将其用作组件连接中的外键。