Почему медленно загружается xml файл?

Моя задача - при изменении языка меню, изменить его везде, во всей игре.
Для этого я создал скрипты
DataHolder - читает настройки из xml и хранит их в своих полях.
XMLReader - читает настройки из xml
XMLWriter - пишет настройки в xml

Все скрипты работают, но чтение запись в xml происходит с задержкой 10 секунд, что для простого однострочного xml файла на ssd нереально долго.

XMLWriter
public static class XMLWriter
{

public static void SetXMLValue(string pathToXMLFile, string nodeName1, string nodeName2, string nodeName2Value)
{  
TextAsset textAsset = Resources.Load<TextAsset>(pathToXMLFile);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(textAsset.text);
XmlNode node = xmlDoc.SelectSingleNode("/"+nodeName1+"/"+nodeName2);
node.InnerText = nodeName2Value;
File.WriteAllText(Application.dataPath + "/Resources/"+pathToXMLFile+".xml", xmlDoc.OuterXml);
}
}


XMLReader
public static class XMLReader
{

public static string GetXMLValue(string pathToXMLFile, string NodeName1, string NodeName2)
{  
TextAsset textAsset = Resources.Load<TextAsset>(pathToXMLFile);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(textAsset.text);
XmlNode node = xmlDoc.SelectSingleNode(NodeName1+"/"+NodeName2);
string nodeValue = node.InnerText;
return nodeValue;
}
}


DataHolder
public static class DataHolder
{
private static string gameLanguage; 

// Обновить данные.
public static void UpdateData()
{	
gameLanguage=XMLReader.GetXMLValue("Settings", "GameSettings", "language");
}
}


Пусть в Settings.xml language = RU

// Изменим его на ENG пишем в файл
XMLWriter.SetXMLValue("GameSettings", "Settings", "language","ENG");

// Обновим данные в DataHolder - прочитаем значения.
DataHolder.UpdateData();
Debug.Log(DataHolder.gameLanguage); // RU


Подождем 3 секунды...RU. Подождем 10 сек - ENG.

Ставил дебаг везде, отслеживал возможные ошибки tre/catch, следил за xml файлом.

По ощущениям - происходит задержка записи в xml файл. Часто значение там изменяется через 5-10 секунд.
В обычных десктопных программах, при работе с xml такого не встречал. Там всё почти мгновенно.

Как это исправить?
  • Вопрос задан
  • 103 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Ezekiel4
Охотник на пиратов и сборщик монолитов
Есть несколько рекомендаций:
1. Используйте асинхронный код. Что-то типа такого:
public static async void SetXMLValue(string pathToXMLFile, string nodeName1, string nodeName2, string nodeName2Value) {  
    TextAsset textAsset = Resources.Load<TextAsset>(pathToXMLFile);
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(textAsset.text);
    XmlNode node = xmlDoc.SelectSingleNode("/" + nodeName1 + "/" + nodeName2);
    node.InnerText = nodeName2Value;
    await File.WriteAllTextAsync(Application.dataPath + "/Resources/" + pathToXMLFile + ".xml", xmlDoc.OuterXml);
}

2. Используйте более быстрые методы чтения и записи XML. Вместо стандартных методов XmlDocument.LoadXml() и XmlDocument.OuterXml вы можете использовать XmlReader и XmlWriter. XmlReader позволяет читать XML файлы по мере их поступления и не хранить их в памяти целиком, что позволяет сократить время чтения. XmlWriter позволяет записывать XML файлы по мере их создания, что позволяет сократить время записи.
3. Используйте кэширование данных в памяти. Вместо того, чтобы каждый раз читать настройки из XML файла, вы можете загрузить их в память при запуске программы и хранить в памяти. При изменении настроек вы можете обновить их как в памяти, так и в XML файле. Это позволит избежать чтения XML файла каждый раз при обращении к настройкам.
4. Используйте более быстрый способ доступа к файлам. Вместо использования метода File.WriteAllText() вы можете использовать методы доступа к файлам, которые более быстры и оптимальны для Unity, например, System.IO.MemoryMappedFiles.
5. Если вам и правда так припекло использовать XML, вы можете немного ускорить процесс, оптимизировав его структуру. Например, выделить для каждой локали по отдельному файлу. Но лично я вам советую познакомиться с форматом JSON, тем более в юнити есть хороший нативный инструмент JsonUtility, а в шарпе newtonsoft.json.

Но если ваша цель не решить интересную задачу, а просто иметь под рукой хороший инструмент, советую вам не мучать себя, а просто воспользоваться пакетом Unity.Localization. Ну или если у вас есть лишних $45, то пакетом i2 в ассет сторе.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы