Но я слышал, что этот способ имеет некоторые проблемы и не подходит для сохранения.
blockquote>Правильно. На некоторых устройствах есть проблемы с
BinaryFormatter
. Это ухудшается при обновлении или изменении класса. Ваши старые настройки могут быть потеряны, так как классы больше не совпадают. Иногда вы получаете исключение при чтении сохраненных данных из-за этого.Кроме того, на iOS вы должны добавить
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
, или у вас будут проблемы сBinaryFormatter
.Самый лучший способ сохранить -
PlayerPrefs
иJson
. Вы можете узнать, как это сделать здесь .В моем случае сохранить формат должен быть байтовый массив
blockquote>В этом случае , вы можете преобразовать его в json, а затем преобразовать массив json
string
вbyte
. Затем вы можете использоватьFile.WriteAllBytes
иFile.ReadAllBytes
для сохранения и чтения массива байтов.Вот общий класс, который можно использовать для сохранения данных. Почти такой же, как , этот , но он не использует
PlayerPrefs
. Он использует файл для сохранения json-данных.
DataSaver
класс:public class DataSaver { //Save Data public static void saveData
(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 (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 (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; } } ИСПОЛЬЗОВАНИЕ:
Пример класса Save :
[Serializable] public class PlayerInfo { public List
ID = new List (); public List Amounts = new List (); 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
("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");
Просто используйте метод DateTime.ParseExact
:
string date = "20121004";
string result = DateTime.ParseExact(date, "yyyyMMdd",
CultureInfo.InvariantCulture).ToString("yyyy-MM-dd");
Это также дает преимущество проверки даты, прежде чем переформатировать ее с помощью дефиса. ParseExact
выдает исключение, которое вы можете поймать, если дата не находится в допустимом диапазоне или формат не соответствует.
Это немного уродливо, но как насчет этого?
date.Insert(6, "-").Insert(4, "-");
Если вы можете предположить, что вы входите со строкой, представляющей действительную дату, и вам не нужно делать какую-либо другую дату -ish логики, то зачем сначала переходить к DateTime
?
Я получаю ошибку:
FormatException: String не была признана действительной DateTime.
blockquote>Вы получаете эту ошибку, потому что не говорите метод ToDateTime (), как разобраться в синтаксическом анализе вашей строки.
Если вы используете следующий метод:
public static DateTime ParseExact( string s, string format, IFormatProvider provider, DateTimeStyles style )
Вы не получите эту ошибку. После генерации переменной DateTime просто отобразите ее в формате
yyyy-dd-mm
с помощью метода ToString ().public string ToString( string format, IFormatProvider provider )
http://msdn.microsoft.com/en-us/library / 8tfzyc64 http://msdn.microsoft.com/en-us/library/9h21f14e Я знаю, что это в основном повторяет ту же информацию, что и все остальные, но также дает ему возможность понять что два метода, которые ему нужно использовать, на самом деле.
string date = "20121004";
date = date.Insert(6,"-");
date = date.Insert(4,"-");
Вот метод расширения, который я использую.
/// <summary>
/// Converts a string to a dateTime with the given format and kind.
/// </summary>
/// <param name="dateTimeString">The date time string.</param>
/// <param name="dateTimeFormat">The date time format.</param>
/// <param name="dateTimeKind">Kind of the date time.</param>
/// <returns></returns>
public static DateTime ToDateTime(this string dateTimeString, string dateTimeFormat, DateTimeKind dateTimeKind)
{
if (string.IsNullOrEmpty(dateTimeString))
{
return DateTime.MinValue;
}
DateTime dateTime;
try
{
dateTime = DateTime.SpecifyKind(DateTime.ParseExact(dateTimeString, dateTimeFormat, CultureInfo.InvariantCulture), dateTimeKind);
}
catch (FormatException)
{
dateTime = DateTime.MinValue;
}
return dateTime;
}