Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.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在完成分析之前遇到流结尾。在for循环中反序列化_C#_Json_Unity3d_Load - Fatal编程技术网

C# 错误:使用BinaryFormatter在完成分析之前遇到流结尾。在for循环中反序列化

C# 错误:使用BinaryFormatter在完成分析之前遇到流结尾。在for循环中反序列化,c#,json,unity3d,load,C#,Json,Unity3d,Load,当我在for循环中使用使用JsonUltility的加载系统时,我遇到了一个问题,它抛出了一个如下的错误: “解析完成前遇到流结束” 保存和加载系统的代码如下所示: 类保存和加载系统的完整示例: public void SaveParty(Player[] players, string nameFile) { Debug.Log("Saving!"); FileStream file = new FileStream(Application.persiste

当我在for循环中使用使用JsonUltility的加载系统时,我遇到了一个问题,它抛出了一个如下的错误:

“解析完成前遇到流结束”

保存和加载系统的代码如下所示:

类保存和加载系统的完整示例:

public void SaveParty(Player[] players, string nameFile)
{
    Debug.Log("Saving!");
    FileStream file = new FileStream(Application.persistentDataPath + nameFile, FileMode.OpenOrCreate);

    try
    {
        // Binary Formatter
        BinaryFormatter formatter = new BinaryFormatter();
        // Serialize
        for(int x = 0; x < players.Length; x++)
        {
            var json = JsonUtility.ToJson(players[x]);
            formatter.Serialize(file, json);
        }
    }
    catch (SerializationException e)
    {
        Debug.LogError("Error Saving: " + e.Message);
    }
    finally
    {
        file.Close();
        Debug.Log(Application.persistentDataPath);
    }
}

// Save Current Party Data
public void SaveCurrentParty()
{
    // If exist will delete, and save again
    if(FirstTimeSaving)
    {
        File.Delete(Application.persistentDataPath + NameFile[1]);
        SaveParty(gameManager.CurrentParty, NameFile[1]);
    }
    // If not exist will save
    if(!FirstTimeSaving)
    {
        SaveParty(gameManager.CurrentParty, NameFile[1]);
        FirstTimeSaving = true;
    }
}

// Load Party Data
public void LoadParty(Player[] party, string nameFile)
{
    Debug.Log("Loading!");
    FileStream file = new FileStream(Application.persistentDataPath + nameFile, FileMode.Open);
    
    try
    {
        BinaryFormatter formatter = new BinaryFormatter();
        // Error Here ↓
        for(int i = 0; i < party.Length; i++)
        {
            JsonUtility.FromJsonOverwrite((string)formatter.Deserialize(file), party[i]);
        }
    }
    catch (SerializationException e)
    {
        Debug.Log("Error Load: " + e.Message);
    }
    finally
    {
        file.Close();
    }
}
public void存储方(播放器[]播放器,字符串名称文件)
{
Log(“保存!”);
FileStream file=newfilestream(Application.persistentDataPath+nameFile,FileMode.OpenOrCreate);
尝试
{
//二进制格式化程序
BinaryFormatter formatter=新的BinaryFormatter();
//连载
对于(int x=0;x
我知道错误是在LoadParty中使用JsonUtility的for循环

这就是我要保存的:

[System.Serializable]
public class Player : MonoBehaviour
{
    // Stats
    public int Hp;
    public int Sp;
    public int level;
    public int St;
    public int Ma;
    public int Ag;
    public int En;
    public int Lu;

    // Items
    public MeleeWeapon Weapon;

    // Skills
    public List<Skills> skills = new List<Skills>();
}
[System.Serializable]
公共类玩家:单一行为
{
//统计数据
公共int Hp;
公共int Sp;
公共智力水平;
公共int St;
公共信息管理硕士;
公共国际公司;
公共国际;
公共int Lu;
//项目
公共近战武器;
//技巧
公共列表技能=新列表();
}

您试图在循环中重复读取相同的
文件流。第一个操作读取文件,并将位置提前到流的末尾。在此之后,将抛出异常,因为流中没有任何内容可供读取

这种情况发生在这里-它与
JsonUtility
无关:

(string)formatter.Deserialize(file)
它将整个流读到最后

在编写时这不是问题,因为序列化的每个对象都会附加到流中

一种解决方案是序列化和反序列化整个
Player[]
。这样,您只能从流中读取一次。打开文件时,您处于位置0—流的开头。读取整个文件并反序列化
Player[]
,而不是单个
Player
对象。完成后,您已经读取了整个流,并且拥有了所有数据

我回避了是否使用二进制序列化的问题。无论数据是如何序列化的,基本原则都适用。

除了

总的来说。。在这里,您已经拥有了一个序列化的JSON
字符串
。。。为什么要对它使用
二进制格式化程序

首先,我将为像这样的玩家创建一个合适的数据容器类

[Serializable]
public class PlayerStats
{
    public int Hp;
    public int Sp;
    public int level;
    public int St;
    public int Ma;
    public int Ag;
    public int En;
    public int Lu;

    
    // Assuming here that both MeleeWepaon and Skills are Serializable types
    public MeleeWeapon Weapon;

    // Skills
    public List<Skills> skills = new List<Skills>();
}

public class Player : MonoBehaviour
{
    public PlayerStats Stats;
}
为什么?->内置的
JsonUtility
不支持数组/列表类型的直接(反)序列化

因此,将此类型序列化,只需将生成的JSON字符串直接写入文件,如

using System.Linq;

[Serializable]
public class PlayersData
{ 
    public PlayerStats[] Data; 

    // Empty constructor is needed by serializer
    public PlayersData(){}

    public PlayersData(IEnumarable<Player> data)
    {
        Data = data.Select(p => p.Stats).ToArray();
    }
}
public void SaveParty(Player[] players, string nameFile)
{
    var path = Path.Combine(Application.persistentDataPath, nameFile);
    Debug.Log($"Saving!");
          
    try
    {
        var json = JsonUtility.ToJson(new PlayersData (players));
        File.WriteAllText(path, json);
        Debug.Log($"Saved to \"{path}\n"); 
    }
    catch (Exception e)
    {
        Debug.LogError($"{e.GetType} while saving: {e.Message}\n{e.StackTrace}");
    }
}
对于加载,只需反过来,只需一次加载整个内容并将其反序列化到包装器容器类中。然后将数据分配给相应的播放器实例

public void LoadParty(Player[] party, string nameFile)
{
    Debug.Log("Loading!");
    var path = Path.Combine(Application.persistentDataPath, nameFile);
    
    try
    {
        var json = File.ReadAllText(path);
        
        var data = JsonUtility.FromJson<PlayersData>(JSON);
        for(var i = 0; i < Mathf.Min(data.Length, party.Length); i++)
        {
            party[i].Stats = data.Data[i];
        }
    }
    catch (Exception e)
    {
        Debug.LogError($"{e.GetType} while loading: {e.Message}\n{e.StackTrace}");
    }
}
public void LoadParty(播放器[]方,字符串名称文件)
{
Log(“加载!”);
var path=path.Combine(Application.persistentDataPath,nameFile);
尝试
{
var json=File.ReadAllText(路径);
var data=JsonUtility.FromJson(JSON);
对于(变量i=0;i


提示:如果您的
Player
有任何
[SerializeField]私有…
字段需要(反)序列化,那么您需要在
Player
中实现setter方法,并使用
PlayerStats
参数“手动”分配它们因此

你的文件内容是什么样子的呢?目前,像是{“Hp”:25,“Sp”:20,“level”:1,“St”:2,“Ma”:0,“Ag”:2,“En”:2,“Lu”:3,“武器”:{“instanceID”:18578},“skills”:[{“instanceID”:18608},{“instanceID”:16468},{“instanceID”:18610},{“instanceID”:16410},{“instanceID”:68},{“instanceID”:68},{“instanceID”:25,“Hp”:25,“Sp”:25,“St”:4,“instanceID”:25,“Sp”:25“{:4,“武器”:{“instanceID”:18578},“技能”:[{“instanceID”:18608},{“instanceID”:16468},{“instanceID”:18610},{“instanceID”:16468}}}请记住,文件是完全动态的,它可以在运行时更改。通常。。在这里,它也没有任何意义,因为数据已经通过JSON进行了序列化(请参见)签入LoadParty,var数据不会被视为数组!,有什么想法吗?@Sfoyarbide解决了这个问题。。它应该是
data.data[i]<