लेकिन मैंने सुना है कि इस तरह के कुछ मुद्दे हैं और सहेजने के लिए उपयुक्त नहीं हैं।
यह सही है। कुछ उपकरणों पर, BinaryFormatter
के साथ समस्याएं हैं। जब आप कक्षा को अपडेट या बदलते हैं तो यह बदतर हो जाता है। कक्षाएं अब मेल नहीं होने के बाद आपकी पुरानी सेटिंग्स खो सकती हैं। कभी-कभी, इसके कारण सहेजे गए डेटा को पढ़ने पर आपको अपवाद मिलता है।
इसके अलावा, आईओएस पर, आपको Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
जोड़ना होगा या आपको BinaryFormatter
में समस्या होगी।
सहेजने का सबसे अच्छा तरीका PlayerPrefs
और Json
के साथ है। आप सीख सकते हैं कि here कैसे करें।
मेरे मामले में, को बचाने के प्रारूप बाइट सरणी होना चाहिए
इस मामले में, आप JSON करने के लिए तो json परिवर्तित string
byte
सरणी करने के लिए इसे बदल सकते हैं। बाइट सरणी को सहेजने और पढ़ने के लिए आप File.WriteAllBytes
और File.ReadAllBytes
का उपयोग कर सकते हैं।
यहां एक जेनेरिक क्लास है जिसका उपयोग डेटा को सहेजने के लिए किया जा सकता है। this के समान लगभग PlayerPrefs
का उपयोग करें। यह जेसन डेटा को सहेजने के लिए फ़ाइल का उपयोग करता है।
DataSaver
वर्ग:
public class DataSaver
{
//Save Data
public static void saveData<T>(T dataToSave, string dataFileName)
{
string tempPath = Path.Combine(Application.persistentDataPath, "data");
tempPath = Path.Combine(tempPath, dataFileName + ".txt");
//Convert To Json then to bytes
string jsonData = JsonUtility.ToJson(dataToSave, true);
byte[] jsonByte = Encoding.ASCII.GetBytes(jsonData);
//Create Directory if it does not exist
if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
}
//Debug.Log(path);
try
{
File.WriteAllBytes(tempPath, jsonByte);
Debug.Log("Saved Data to: " + tempPath.Replace("/", "\\"));
}
catch (Exception e)
{
Debug.LogWarning("Failed To PlayerInfo Data to: " + tempPath.Replace("/", "\\"));
Debug.LogWarning("Error: " + e.Message);
}
}
//Load Data
public static T loadData<T>(string dataFileName)
{
string tempPath = Path.Combine(Application.persistentDataPath, "data");
tempPath = Path.Combine(tempPath, dataFileName + ".txt");
//Exit if Directory or File does not exist
if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
{
Debug.LogWarning("Directory does not exist");
return default(T);
}
if (!File.Exists(tempPath))
{
Debug.Log("File does not exist");
return default(T);
}
//Load saved Json
byte[] jsonByte = null;
try
{
jsonByte = File.ReadAllBytes(tempPath);
Debug.Log("Loaded Data from: " + tempPath.Replace("/", "\\"));
}
catch (Exception e)
{
Debug.LogWarning("Failed To Load Data from: " + tempPath.Replace("/", "\\"));
Debug.LogWarning("Error: " + e.Message);
}
//Convert to json string
string jsonData = Encoding.ASCII.GetString(jsonByte);
//Convert to Object
object resultValue = JsonUtility.FromJson<T>(jsonData);
return (T)Convert.ChangeType(resultValue, typeof(T));
}
public static bool deleteData(string dataFileName)
{
bool success = false;
//Load Data
string tempPath = Path.Combine(Application.persistentDataPath, "data");
tempPath = Path.Combine(tempPath, dataFileName + ".txt");
//Exit if Directory or File does not exist
if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
{
Debug.LogWarning("Directory does not exist");
return false;
}
if (!File.Exists(tempPath))
{
Debug.Log("File does not exist");
return false;
}
try
{
File.Delete(tempPath);
Debug.Log("Data deleted from: " + tempPath.Replace("/", "\\"));
success = true;
}
catch (Exception e)
{
Debug.LogWarning("Failed To Delete Data: " + e.Message);
}
return success;
}
}
उपयोग:
उदाहरण वर्ग सहेजें करने के लिए:
[Serializable]
public class PlayerInfo
{
public List<int> ID = new List<int>();
public List<int> Amounts = new List<int>();
public int life = 0;
public float highScore = 0;
}
डेटा सहेजें:
PlayerInfo saveData = new PlayerInfo();
saveData.life = 99;
saveData.highScore = 40;
//Save data from PlayerInfo to a file named players
DataSaver.saveData(saveData, "players");
लोड डाटा:
PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players");
if (loadedData == null)
{
return;
}
//Display loaded Data
Debug.Log("Life: " + loadedData.life);
Debug.Log("High Score: " + loadedData.highScore);
for (int i = 0; i < loadedData.ID.Count; i++)
{
Debug.Log("ID: " + loadedData.ID[i]);
}
for (int i = 0; i < loadedData.Amounts.Count; i++)
{
Debug.Log("Amounts: " + loadedData.Amounts[i]);
}
हटाएं डाटा:
DataSaver.deleteData("players");
क्यों अपने प्रारूप एक बाइट सरणी होना चाहिए? इसे PlayerPrefs में क्यों न सहेजें? –
क्रमबद्धरण का उपयोग करने में समस्या क्या है? –