Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
保存自定义C#类(包含各种大小的列表/数组)而不是binaryformatter.serialize的推荐过程?_C#_Unity3d_Serialization_Binaryformatter - Fatal编程技术网

保存自定义C#类(包含各种大小的列表/数组)而不是binaryformatter.serialize的推荐过程?

保存自定义C#类(包含各种大小的列表/数组)而不是binaryformatter.serialize的推荐过程?,c#,unity3d,serialization,binaryformatter,C#,Unity3d,Serialization,Binaryformatter,我希望用户能够在我的应用程序中创建网格样式的“地图”,将它们保存到磁盘,然后与其他人共享。在基本地图数据中,我希望用户输入他们的姓名,以便“声明”他们的工作 为了更安全一点,我考虑将map类(带有艺术家名称、地图尺寸、其他有用选项和平面/2D数组/列表[根据需要删除])保存为二进制。所以,XML(人类可读)可能不是我要使用的。。。但我还没有完全反对他们,只是谨慎地停止“偷窃” 我一直在使用BinaryFormatter.Serialize方法,但是随着tiledata的大小从200*200分片增

我希望用户能够在我的应用程序中创建网格样式的“地图”,将它们保存到磁盘,然后与其他人共享。在基本地图数据中,我希望用户输入他们的姓名,以便“声明”他们的工作

为了更安全一点,我考虑将map类(带有艺术家名称、地图尺寸、其他有用选项和平面/2D数组/列表[根据需要删除])保存为二进制。所以,XML(人类可读)可能不是我要使用的。。。但我还没有完全反对他们,只是谨慎地停止“偷窃”

我一直在使用BinaryFormatter.Serialize方法,但是随着tiledata的大小从200*200分片增加到300*300分片,反序列化所需的时间从6.5秒增加到33秒,并以指数方式继续增加

如果可能的话,我希望能够存储2000*2000的地图数据

所以,除了学习压缩技术(我无论如何都会这样做以减少文件大小)之外,我想知道是否还有其他序列化程序推荐我使用。我已经看到有一些第三方游戏可用,但需要弄清楚它们是否与Unity兼容(是的……我是自学成才的noob游戏开发人员)

如蒙协助,将不胜感激

为清晰起见,添加了当前测试代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class FileReaderTest : MonoBehaviour
{
    public int xlimit = 300;
    public int ylimit = 300;

    // Use this for initialization
    void Start()
    {
        Save();
    }


    // Update is called once per frame
    void Update()
    {
    if (Input.anyKeyDown)
        Load();
    }

    private void Save()
    {
        BinaryFormatter formatter = new BinaryFormatter();

        FileStream file = File.Open(Application.dataPath + "/saved.data", FileMode.OpenOrCreate);

        List<TestDataBaseEntry> mapTileData = new List<TestDataBaseEntry>();
        List<TestDataBaseEntry> extraMapTileData = new List<TestDataBaseEntry>();

        for (int x = 0; x < xlimit; x++)
        {
            for (int y = 0; y < ylimit; y++)
            {
                // Simulating random data
                mapTileData.Add(new TestDataBaseEntry(TileState.Filled, x, y));
            }
        }

        for (int x = 0; x < 5; x++)
        {
            for (int y = 0; y < 3; y++)
            {
                extraMapTileData.Add(new TestDataBaseEntry(TileState.Ignore, x, y));
            }
        }


        TestMapFile newFile = new TestMapFile("Mike", xlimit, ylimit, mapTileData, extraMapTileData);

        formatter.Serialize(file, newFile);
        file.Close();

        Debug.Log("saved");
    }

    private void Load()
    {
        float starttime = Time.realtimeSinceStartup;
        if (File.Exists(Application.dataPath + "/saved.data"))
        {
            using (FileStream file = File.Open(Application.dataPath + "/saved.data", FileMode.Open))
            {
                BinaryFormatter formatter = new BinaryFormatter();

                TestMapFile retrievedTestMapFile = (TestMapFile) formatter.Deserialize(file);
            }
        }

        Debug.Log("Loaded");
        Debug.Log("The process took " + (Time.realtimeSinceStartup - starttime));
    }

}

[Serializable]
public class TestDataBaseEntry
{
    public TileState tileState;
    public int x;
    public int y;

    public TestDataBaseEntry(TileState newTileState, int newX, int newY)
    {
        tileState = newTileState;
        x = newX;
        y = newY;
    }
}

[Serializable]
public class TestMapFile
{
    public int xSize;
    public int ySize;
    public List<TestDataBaseEntry> mapTileData = new List<TestDataBaseEntry>();
    public List<TestDataBaseEntry> mapExtraTileData = new List<TestDataBaseEntry>();
    public string createdBy;

    public TestMapFile(string artist, int newXSize, int newYSize, List<TestDataBaseEntry> newDB, List<TestDataBaseEntry> newExtraDB)
    {
        createdBy = artist;
        xSize = newXSize;
        ySize = newYSize;
        mapTileData = newDB;
        mapExtraTileData = newExtraDB;
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用制度;
使用System.IO;
使用System.Runtime.Serialization.Formatters.Binary;
公共类FileReaderTest:MonoBehavior
{
公共int xlimit=300;
公共int ylimit=300;
//用于初始化
void Start()
{
Save();
}
//每帧调用一次更新
无效更新()
{
如果(输入。anyKeyDown)
加载();
}
私有void Save()
{
BinaryFormatter formatter=新的BinaryFormatter();
FileStream file=file.Open(Application.dataPath+“/saved.data”,FileMode.OpenOrCreate);
List mapTileData=新列表();
List extraMapTileData=新列表();
对于(int x=0;x
看看protobuf网络。它的可读性不强,速度很快,占用的磁盘空间也较少。

好的,我从Unity论坛上的一篇帖子中听取了建议,也考虑了这里提到的一些要点,并创建了一些测试脚本——以下是我的发现

首先,根据@Scott Hannen在评论中提到的内容(在forum.Unity.com上的前一篇帖子中也提到过),我尝试制作自己的反序列化程序,我剥离了要放入的信息(并从中读取)文件,并将时间缩短到0.13秒,以获得足够的信息,为1920*1080大小的地图重新创建地形。我处理的数据只是一个字符串、2个整数和一个布尔平面数组

然后我又回去看二进制格式化程序。为了使比较相互关联,我必须解决的最大区别是将自定义类TestDataBaseEntry的列表更改为bool数组(这是我在binarywriter中使用的)。仅此一项就将读取文件的时间从300*300地图大小的33.3秒减少到1920*1080地图大小的11.1秒!!!一个巨大的改进-我猜BinaryFormatter的一些过程是大量的背景检查和错误检查

所以它仍然不如我的剥离式自定义序列化程序快。然而,这仍然不是一个真正的比较,因为我仍然使用BinaryFormatter反序列化一个实际的类,而我使用BinaryWriter/BinaryReader单独反序列化该类的组件

所以我还有更多的测试要做,但到目前为止,我的解决方案似乎是简化我试图写给fil的信息