Saving and Loading Binary List<>

hi guys i need some help saving and loading this is my code. can u tell me what is wrong?

DataBase

/************************************************************************** UserData **************************************************************************/
    public static void SaveUserInventory(List<Item> item){
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create (Application.persistentDataPath + "/UserInventory.dat");
        bf.Serialize(file, p_items);
        file.Close();
    }

    public static void LoadUserInventory(){
        if (File.Exists (Application.persistentDataPath + "/UserInventory.dat")) {
            BinaryFormatter bf = new BinaryFormatter ();
            FileStream file = File.Open (Application.persistentDataPath + "/UserInventory.dat", FileMode.Open);
            p_items = (List<Item>)bf.Deserialize (file);
            file.Close ();
        }
    }

Item Code

using UnityEngine;
using System.Xml;
using System.Xml.Serialization;

public enum ItemType {None,Avatar,Car,Wheel,Power}
public enum WheelType{None,Asphalt,Mountain,Air,Water,Snow,Gravity}
public enum PowerType {None,NonFollower,Follower,Support,Droppable}

[System.Serializable]
public class Item{
    [Header("Item Info")]
    [XmlEnum("ID")]
    public int ID = 0;
    [XmlAttribute("name")]
    public string name = string.Empty;
    [XmlElement("description")]
    public string description = string.Empty;
    [XmlElement("price")]
    public int price = 0;
    [XmlElement("itemType")]
    public ItemType itemType = ItemType.None;

    [Header("Wheel")]
    [XmlElement("wheelOrnament")]
    public bool wheelOrnament = false;
    [XmlElement("wheelOrnamentName")]
    public string wheelOrnamentName = "";
    [XmlElement("wheelType")]
    public WheelType wheelType = WheelType.None;

    [Header("Power")]
    [XmlElement("powerCharges")]
    public int powerCharges = 0;
    [XmlElement("powerCanBehind")]
    public bool powerCanBehind = false;
    [XmlElement("powerType")]
    public PowerType powerType = PowerType.None;
    [XmlElement("powerBoost")]
    public bool powerBoost = false;
    [XmlElement("powerSlower")]
    public bool powerSlower = false;
    [XmlElement("powerHit")]
    public bool powerHit = false;
    [XmlElement("powerJump")]
    public bool powerJump = false;
    [XmlElement("powerSpin")]
    public bool powerSpin = false;
    [XmlElement("powerWiggle")]
    public bool powerWiggle = false;

    [Header("Item Status")]
    [XmlElement("isActive")]
    public bool isActive = true;
}

ERROR

SerializationException: Unexpected binary element: 255
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:254)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject (BinaryElement element, System.IO.BinaryReader reader) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:130)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph (BinaryElement elem, System.IO.BinaryReader reader, Boolean readHeaders, System.Object& result, System.Runtime.Remoting.Messaging.Header[]& headers) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:104)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:179)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:136)
DataBase.LoadUserInventory () (at Assets/Scripts/_DataBase/DB.cs:57)
Main.Awake () (at Assets/Scripts/General/Main.cs:74)

DB 57: p_items = (List)bf.Deserialize (file);
Main 74; DataBase.LoadUserInventory ();

Are you targeting iOS/WebGL/any of the AOT compiled platforms? If so I believe you might need to do the following:

Furthermore, you do know that the ‘XmlElementAttribute’ is for the XmlSerializer and that the BinaryFormatter would completely ignore those attributes?

Also, why do your SaveUserInventory method take in a List, but not use it for anything, and instead modifies some global ‘p_items’ variable scoped elsewhere? Same with the LoadUserInventory, why does it set the ‘p_items’ instead of return the List?

1 Like

i have items database with xml . and i need to save a user invetory when they buy something.

i try with out XML Format and now look

Item Class

using UnityEngine;

public enum ItemType {None,Avatar,Car,Wheel,Power}
public enum WheelType{None,Asphalt,Mountain,Air,Water,Snow,Gravity}
public enum PowerType {None,NonFollower,Follower,Support,Droppable}

[System.Serializable]
public class Item{

    public int ID = 0;
    public string name = string.Empty;
    public string description = string.Empty;
    public int price = 0;
    public ItemType itemType = ItemType.None;

    public bool wheelOrnament = false;
    public string wheelOrnamentName = "";
    public WheelType wheelType = WheelType.None;

    public int powerCharges = 0;
    public bool powerCanBehind = false;
    public PowerType powerType = PowerType.None;
    public bool powerBoost = false;
    public bool powerSlower = false;
    public bool powerHit = false;
    public bool powerJump = false;
    public bool powerSpin = false;
    public bool powerWiggle = false;

    public bool isActive = true;
}

Load and Save Function

DataBase.LoadUserInventory ();
        if (DataBase.p_items != null) {
            Debug.Log ("From DB");
            _userItems = DataBase.p_items;

        } else {
            Debug.Log ("Free Items");
            _userItems = _freeItems;
            DataBase.SaveUserInventory (_freeItems);
        }

Database.css

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

public class DataBase {
    /* User Inventory*/
    public static List<Item> p_items;

    /************************************************************************** UserData **************************************************************************/
    public static void SaveUserInventory(List<Item> item){
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create (Application.persistentDataPath + "/UserIn.dat");
        bf.Serialize(file, p_items);
        file.Close();
    }

    public static void LoadUserInventory(){
        if (File.Exists (Application.persistentDataPath + "/UserIn.dat")) {
            BinaryFormatter bf = new BinaryFormatter ();
            FileStream file = File.Open (Application.persistentDataPath + "/UserIn.dat", FileMode.Open);
            p_items = (List<Item>)bf.Deserialize (file);
            file.Close ();
        }
    }
}