- Home /
How can I save and load files on android?
I have this script that works flawlessly while testing on my computer, but doesn't work on my Pixel 4. Does anybody have any idea why this won't work or how to fix it?
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static class SaveSystem
{
static readonly string fileType = ".json";
static readonly BinaryFormatter formatter = new();
public static void SaveTeam (Team team, string folder)
{
var fileName = Application.persistentDataPath + "/" + folder + "/" + team.index + fileType;
FileStream stream = new (fileName, FileMode.Create);
TeamData teamData = TeamData.SaveTeam(team);
formatter.Serialize(stream, teamData);
stream.Close();
Debug.Log("Saved " + team.Name + " Team to " + fileName);
}
public static void LoadTeam (Team team, string folder)
{
var fileName = Application.persistentDataPath + "/" + folder + "/" + team.index + fileType;
if (File.Exists(fileName))
{
FileStream stream = new(fileName, FileMode.Open);
TeamData data = formatter.Deserialize(stream) as TeamData;
stream.Close();
data.LoadTeam(team);
Debug.Log("Loaded "+team.Name+" Team from "+fileName);
}
else
{
Debug.Log("File not found in " + fileName);
}
}
public static float[] ColorToArray (Color color)
{
float[] array = new float[3];
array[0] = color.r;
array[1] = color.g;
array[2] = color.b;
return array;
}
public static Color ArrayToColor(float[] array)
{
Color color = Color.white;
color.r = array[0];
color.g = array[1];
color.b = array[2];
return color;
}
}
[System.Serializable]
public class TeamData
{
public string Name;
public float[] color;
public static TeamData SaveTeam (Team team)
{
TeamData data = new();
data.Name = team.Name;
data.color = SaveSystem.ColorToArray(team.primaryColor);
return data;
}
public void LoadTeam (Team team)
{
team.Name = Name;
team.primaryColor = SaveSystem.ArrayToColor(color);
}
}
For mobile, I suggest using player prefs instead of binary because mobile doesn't need too much of a complicated script just to save and load some data.
Does mobile platform define the complexity of a savegame required?
PlayerPrefs is a storage medium, not a serializer
Answer by Pangamini · May 17 at 08:01 AM
I am not exactly sure what's wrong, but I have two points:
Use System.IO.Path.Combine instead of concatenating strings with "/", directory separator is platform specific.
Don't use BinaryFormatter. This is from the Microsoft docs:
The BinaryFormatter type is dangerous and is not recommended for data processing. Applications should stop using BinaryFormatter as soon as possible, even if they believe the data they're processing to be trustworthy. BinaryFormatter is insecure and can't be made secure.
You need to be more specific, the "doesn't work" gives no information at all. Does it throw any exceptions? Does it write but the output is wrong? What exactly is failing?
How would I write a file location using the path combine method? What could I use in place of Binary Formatter? I'm not completely sure why it doesn't work. All I know is that when I save the team data, and restart the app, it doesn't load anything it should have saved.
File location: Just go and see the documentation of Path.Combine (literally put it to google).
In place of binary formatter, well, in this particular case you'd be good with using Unity's JsonUtility. The security issue stems from the fact that the type of object being deserialized is part of the data, and thus the data (the savegame) could potentially describe a structure of objects of classes completely unrelated to your game. Imagine that you load a savegame that, during the deserialization, creates a http request that posts your local files. For the games, I usually end up writing a custom serialization, but you can go through some plugins on asset store. But again, in your case, the JsonUtility should suffice.
About the "what's wrong", it;s up to you to find what's not working. Is the data written? Are you even calling the Save method? Is the data written in correct format? Is the load actually called? Was the data read correctly? Are you using the data after it's deserialized? Do you have any output in the console about error logs or exceptions? Debug.
I looked into both of your suggestions and after implementing some changes, when combined, everything works, even on my phone. Thankyou so much! The tutorial I followed for the process must have been pretty outdated.