Работа с файлами

    Универсальный скрипт для работы с файлами на GDscript 3.5


    Основная идея полягает в том, чтобы не переписывать килобайты строк производя одни и те же действия.


    В этой публикации:


    • Пример кода и описание функций в отдельности

    • Приеры реального использования

    • Полный, готовый скрипт для ваших проектов.



    При разработке современных игр, будь то стратегия или RPG, как для сохранений прогресса, так и для хранения других данных игры, нужен доступ к работе с файлами.


    Поскольку это на протяжении всего проекта встречается очень часто и в один момент нужно получить данные, а в другой наоборот записать на тот случай если данные очень важны и при каком либо форс-мажоре не должны потеряться, к примеру банальный вылет игры или пользователь закрыл игру без сохранения.
    На такие случаи разработчик и заботится о промежуточных сохранениях определённых данных.


    Первая функция, это создание файла.


    Предположим, что игра только установлена и нужны первичные данные об игроке.
    Для начала, при создании файла запишем только имя персонажа.


  • Скрипт функции.


  • # Функция для создания нового файла
    func new_f(name: String, text_n: String):
    var file = File.new()
    # Открываем файл для записи, если файл не существует, он будет создан
    if file.open(name, File.WRITE) == OK:
    file.store_line(text_n) # Записываем строку в файл
    file.close() # Закрываем файл
    return "1"
    else:
    return "0"


    Функция при успешном создании файла вернёт строку 1 и в случай неудачи 0



  • Пример вызова


  • var profil_f = "user://gamer.cfd" #Переменная для хранения пути и имени файла

    new_f(profil_f, "Name") #Вызов функции для создания файла с текстом Name в первой строке

    Как видно, гораздо проще вызвать функцию так
    new_f("user://gamer.cfd", "Name")

    чем каждый раз переписывать весь код.


    Ну а если нужен результат выполнения в переменной для логики дальнейших действий, то делаем так:



    var result = new_f("user://gamer.cfd", "Name")
    if result = "1":
    print("Файл создан!")
    else:
    print("Файл не создан!")

    Думаю, что основной принцеп понятен и далее ненужно долго расписывать.



    Чтение всего файла


    В процессе игры, вам может понадобиться записывать попутно какие-то данные и в коком-то месте считывать не определённую строку, а сразу весь файл прогресса.
    К примеру, был диалог с определённым NPC с ответами на его вопросы и нужно сохранить историю диалога для просмотра в дальнейшем, или может отчёты о событиях, или логи ошибок и т.д..
    Для этого и нужна такая функция, как чтение всего файла на устройстве игрока.

    Внимание!
    В игровом движке Godot есть различие между хранением и чтением файлов в директориях!
    А именно, user:// и res://
    Так как изменять файлы в user:// на устройстве игрока можно и динамически с ними работать, а в папке самой игры res:// нельзя! Можно только читать!


  • Скрипт функции.


  • # Функция для чтения всего файла
    func read_all_f(name: String):
    var profil_f = "user://gamer.cfd"
    if File.new().file_exists(name):
    #print("Файл существует!")
    var file = File.new() # Создаём объект файла
    file.open(name, File.READ) # Открываем файл для чтения
    var line = file.get_as_text()
    file.close() # Закрываем файл
    return line
    else:
    return "0"


  • Вызов функции.


  • var text_log = "user://game_log.cfd"
    var result = read_all_f(text_log)
    print ("Текст из файла: ", result)

    Аналогично можно читать файлы из папки самой игры.
    К примеру, тексты в которых описываются задания или предписания, ну или вступительные/финальные титры.



    var preview_text = "res://text/preview.txt"
    var result = read_all_f(preview_text )
    print ("Текст из файла превью: ", result)


    Чтение нескольких строк из файла


    Довольно часто бавает так, что нужно считывать несколько строк одного и того же файла.
    К примеру, при постройке шахты, нужно получить остаток дерева и железа на складе у игрока.


    Конечно же, можно просто несколько раз вызвать функцию чтения одной строки, о ней речь пойдёт далее, но гораздо удобнее в этом случае, один раз открыть файл, получить все строки и выбрать только определённые.


    И так, у нас есть файл, в котором мы вот так храним данные о запасах:
    Дерево
    Камень
    Железо

    Нам нужно узнать, сколько у нашего игрока железа и камня.
    В файле это записано так:
    152
    12
    38

    Следовательно, нам нужно получить первую и третью строки.



    # Функция для чтения определённых, нескольких строк с загрузкой всего файла
    func read_all_str_f(name: String, line_nums: String):
    if File.new().file_exists(name):
    var file = File.new()
    file.open(name, File.READ)

    var lines = file.get_as_text().split("\n") # Читаем весь файл и разбиваем на строки
    file.close()

    var indices = line_nums.split(":") # Разбиваем строку параметров "1:3:5" на список
    var result = []

    for index in indices:
    var line_index = int(index) - 1 # Преобразуем строку в число и сдвигаем на -1 (чтобы начиналось с 0)
    if line_index >= 0 and line_index < lines.size():
    result.append(lines[line_index])
    else:
    result.append("0") # Если строки нет, добавляем "0"

    return ":".join(result) # Возвращаем результат в виде строки через ":"
    else:
    return "0"


  • Вызов функции



  • # Пример вызова
    var data = read_all_str_f("user://gamer.cfd", "1:3")
    print(data) # Например, может вывести "152:38"

    # Разбиваем строку на переменные
    var parts = data.split(":")
    var wood = parts[0]
    var metal = parts[1]

    print(wood, metal)

    В этой функции используется разделитель строк :
    Количество строк неограничено, то есть можно перечислить к примеру 5 или 50 строк таким образом
    3:15:17:28:34:35:36:75
    Соответственно и принять результат и разложить по переменным:



    # Разбиваем строку на переменные
    var parts = data.split(":")
    var val_1 = parts[0]
    var val_2 = parts[1]
    var val_2 = parts[2]
    var val_3 = parts[3]
    var val_4 = parts[4]
    var val_5 = parts[5]
    var val_6 = parts[6]
    var val_7 = parts[7]
    var val_8 = parts[8]

    Это очень удобно, когда к примеру у вас в одном файле хранится вся статистика и профиль игрока и вам нужно получить только определённые значения из определённых строк.



    Функция для чтения определённой строки


    На тот случай, когда вам нужно получить только одно значение из определённой строки, есть такая функция.


  • Скрипт функции:


  • # Функция для чтения определённой строки
    func read_str_f(name: String, line_num: int):
    if File.new().file_exists(name):
    var file = File.new()
    file.open(name, File.READ)

    var line = ""
    for i in range(line_num): # Читаем строки до нужной
    if file.eof_reached(): # Проверяем, не закончился ли файл раньше
    file.close()
    return "0"
    line = file.get_line()

    file.close()
    return line
    else:
    return "0"

    В отличии от предыдущей функции, эта функция вернёт результат только той строки, которую вы указали.
    К примеру, игрок добывает камень и нужно добавить одну единицу.
    Вы сначала считываете значение из нужной строки, потом добавляете 1 и дальше делаете то, что вам нужно с этими данными.
    Ну или получить имя игрока, значение LVL или HP, ну и т.д.


  • Пример вызова:


  • # Получить 5-ю строку
    var profil_f = "user://gamer.cfd"
    var line5 = get_line_number(profil_f, 5)
    print(line5)

    Такая функция нужна постоянно.



    Функция для записи данных в файл


    С чтением данных мы разобрались, теперь перейдём к записи данных.
    Эта функция записывает данные в начало или в конец файла в зависимости от установленного флага


  • Скрипт функции


  • #Функция для записи данных в файл
    func dop_f(name: String, text_n: String, mode: int):
    var file = File.new()
    # Проверяем существование файла
    var file_exists = file.file_exists(name)
    # Открываем файл в нужном режиме
    if file.open(name, File.WRITE_READ) == OK:
    if mode == 1 and file_exists:
    # Читаем старое содержимое
    var old_content = file.get_as_text()
    file.seek(0) # Перемещаем курсор в начало
    file.store_string(text_n + "\n" + old_content) # Записываем новый текст + старое содержимое
    elif mode == 2:
    file.seek_end() # Перемещаем курсор в конец
    file.store_line(text_n) # Добавляем строку в конец
    else:
    file.store_line(text_n) # Если файла не было, просто создаём и пишем строку
    file.close()
    return "1"
    else:
    return "0"

    В этой функции определяется место записи при вызове в третьем параметре цифрой 1 или 2.


  • Пример вызова


  • # Дописываем данные
    var profil_f = "user://gamer.cfd"
    var result1 = new_f(profil_f, "Добавлено в начало", 1) # Добавляет в начало

    var result2 = new_f(profil_f, "Добавлено в конец", 2) # Добавляет в конец

    print(result1, result2)

    Как видно в примерах вызова, в первом вызове текст допишется в начало файла, во втором в конец о чём и говорят флаги 1 и 2.



    Функция для обновления всего файла


    Эта функция нужна в тех случаях, если нужно допустим перезаписать сохранение в игре, к примеру по нажатию кнопки F5, ну или из меню сохранения.
    Так же, если обнулить какие-то параметры для персонажа или NPC. Да в общем, много где можно применять когда нужно обновить весь файл.


  • Скрипт функции:


  • # Обновляем весь файл
    func upd_f(name: String, new_text: String):
    var file = File.new()
    # Открываем файл в режиме WRITE (очищает старое содержимое)
    if file.open(name, File.WRITE) == OK:
    file.store_string(new_text) # Записываем новые данные
    file.close()
    return "1"
    else:
    return "0"


  • Пример вызова:


  • # Обновляем весь файл
    var profil_f = "user://gamer.cfd"
    var result = update_f(profil_f, "Это новый текст файла")
    print(result) # Выведет "1" при успешной записи

    Так же, эту функцию можно использовать тогда, когда сам файл нужно оставить но всё содержимое очистить, для этого можно просто вызвать её с пустым текстом в параметре



    # Очищаем весь файл
    var profil_f = "user://gamer.cfd"
    var result = update_f(profil_f, "")
    print(result) # Выведет "1" при успешной очистке


    Функция для обновления определённой строки


    В процессе игры, довольно часто бывают ситуации когда нужно из множества строк в файле обновить всего одну.
    Для этого так же есть опредилённая функция.


  • Скрипт функции:


  • # Обновляем только одну строку
    func upd_str_f(name: String, line_num: int, text: String):
    var file = File.new()
    # Проверяем, существует ли файл
    if not file.file_exists(name):
    return "0"
    # Открываем файл для чтения
    if file.open(name, File.READ) != OK:
    return "0"
    var lines = file.get_as_text().split("\n") # Читаем все строки
    file.close()
    # Проверяем, что номер строки в допустимых пределах
    if line_num < 1 or line_num > lines.size():
    return "0"
    lines[line_num - 1] = text # Обновляем нужную строку (нумерация с 0)
    # Перезаписываем файл с обновлёнными строками
    if file.open(name, File.WRITE) == OK:
    file.store_string("\n".join(lines)) # Записываем новый текст
    file.close()
    return "1"
    else:
    return "0"

    Это полезно, когда нужно обновить количество определённого ресурса, добытого в процессе игры или уровень героя.
    Приминений огромное количество.


  • Пример вызова:


  • # Обновляем вторую строку:
    var profil_f = "user://gamer.cfd"
    var result = upd_str_f(profil_f, 2, "Обновлённая строка")
    print(result) # Выведет "1" при успешном обновлении

    Первый параметр как и всегда, это имя файла, второй, какую строку нужно обновить (Незабываем, что строки начинаются не с 1 а с 0), ну и третий параметр это новое значение выбранной строки.



    Функция для обновления части строки


    Конечно же, можно было обойтись и без этой функции, просто считывая определённую строку, разбирая её, обновляя и перезаписывая в файл при помощи двух описанных выше функций, но на случай когда вы точно знаете в каком месте и какую часть данных нужно обновить или удалить, то эта функция придётся очень кстати.


  • Скрипт функции


  • # Функция обновляет часть строки с позиции beg до end
    func upd_part_str_f(name: String, line_num: int, beg: int, end: int, text: String):
    var file = File.new()
    # Проверяем, существует ли файл
    if not file.file_exists(name):
    return "0"
    # Открываем файл для чтения
    if file.open(name, File.READ) != OK:
    return "0"
    var lines = file.get_as_text().split("\n") # Читаем все строки
    file.close()
    # Проверяем, что номер строки в допустимых пределах
    if line_num < 1 or line_num > lines.size():
    return "0"
    var line = lines[line_num - 1] # Получаем нужную строку (нумерация с 0)
    # Проверяем, что индексы находятся в пределах строки
    if beg < 0 or beg >= line.length() or end < beg or end > line.length():
    return "0"
    # Обновляем только нужную часть строки
    lines[line_num - 1] = line.substr(0, beg) + text + line.substr(end)
    # Перезаписываем файл с обновлёнными строками
    if file.open(name, File.WRITE) == OK:
    file.store_string("\n".join(lines)) # Записываем новый текст
    file.close()
    return "1"
    else:
    return "0"

    Эту функцию удобно использовать так же тогда, когда у вас данные хранятся не в нескольких строках а все в одной.
    К примеру, несколько NPC на одном уровне:
    npc001 x=102 y=002 z=015 hp=100
    npc002 x=157 y=002 z=225 hp=097
    npc003 x=253 y=002 z=787 hp=051
    Вот какраз на такой случай и пригодится эта функция.
    Обратите внимание на структуру записи!
    Здесь используется чёткое количество символов. Это сделано для того, чтобы не путаться в позиции определённого параметра. Конечно же, вы можете делать как вам удобнее, это просто пример хранения а не обязательное правило.
    Как пример, вы точно знаете что делать и в каком случае с определённым npc и записываете данные без нулей в начале.
    npc1 x=102 y=2 z=15 hp=100
    npc2 x=157 y=2 z=225 hp=97
    npc3 x=253 y=2 z=787 hp=51
    В таком случае, вызов с указанием позиции нужно определять для каждого npc свой и знать в какой позиции сейчас какой символ.


  • Пример вызхова:


  • # Обновляем HP у второго npc по первому варианту с нулями в начале:
    var npc_data = "user://npc.cfd"
    var result = upd_part_str_f(npc_data, 2, 28, 30, "085")
    print(result) # Выведет "1" при успешном обновлении

    Как видно из этого примера, мы обновили значение HP у второго npc с 097 до 085
    Так как цифра 097 начинается с позиции 28 и заканчивается 30
    Это потому, что пробелы тоже считаются как символы!



    Чтение части строки в файле


    В дополнение предыдущей функции, так же есть функция в которой можно просто прочитать нужную часть строки. Принцип тот хе, но не для замены, а просто для чтения.


  • Скрипт функции:


  • # Чтение части строки
    func read_part_str_f(name: String, line_num: int, beg: int, end: int) -> String:
    var file = File.new()
    # Проверяем, существует ли файл
    if not file.file_exists(name):
    return "0"
    # Открываем файл для чтения
    if file.open(name, File.READ) != OK:
    return "0"
    var lines = file.get_as_text().split("\n") # Читаем все строки
    file.close()
    # Проверяем, что строка существует
    if line_num < 1 or line_num > lines.size():
    return "0"
    var line = lines[line_num - 1] # Получаем нужную строку (нумерация с 0)
    # Проверяем, что индексы находятся в пределах строки
    if beg < 0 or beg >= line.length() or end < beg or end > line.length():
    return "0"
    # Возвращаем часть строки
    return line.substr(beg, end - beg)

    Эту функцию, можно вызывать перед обновлением части строки, что-бы получить данные и обработать их, а уже потом с помощью предыдущей функции перезаписать.


  • Пример вызова:


  • # Читаем часть данных:
    var npc_data = "user://npc.cfd"
    var data = read_part_str_f(npc_data, 2, 28, 30)
    print(data) # Выведет часть строки с 28-го по 30-й символ

    Таким образом, можно проверить и убедиться, что будут обновлены нужные данные без ошибки.



    Функция для удаления строки из файла


    Так же очень полезной будет функция для удаления определённой строки из файла, так как не всегда удобно обновлением файла вырезать определённую строку, да и по сути, нужно каждый раз переберать весь файл и искать что убрать. В общем, довольно большую часть рутины берёт на себя эта функция.


  • Скрипт функции:


  • # Функция для удаления строки из файла
    func del_str_f(name: String, line_num: int):
    var file = File.new()
    # Проверяем, существует ли файл
    if not file.file_exists(name):
    return "0"
    # Открываем файл для чтения
    if file.open(name, File.READ) != OK:
    return "0"
    var lines = file.get_as_text().split("\n") # Читаем все строки
    file.close()
    # Проверяем, что номер строки в допустимых пределах
    if line_num < 1 or line_num > lines.size():
    return "0"
    # Удаляем нужную строку
    lines.remove(line_num - 1) # Нумерация с 0, поэтому уменьшаем на 1
    # Перезаписываем файл без удалённой строки
    if file.open(name, File.WRITE) == OK:
    file.store_string("\n".join(lines)) # Записываем новый текст
    file.close()
    return "1"
    else:
    return "0"

    Её можно использовать в комбинации с функцией read_part_str_f если к примеру HP у npc 000 и удалять данные о npc вообще, если они больше ненужны.
    Это один из примеров, так как ситуаций для удаления строки может быть намного больше.


  • Пример вызова:


  • # Удаляем строку 2:
    var npc_data = "user://npc.cfd"
    var result = del_str_f(npc_data, 2)
    print(result) # Выведет "1" при успешном удалении строки

    Таким образом, мы удалили данные о npc002 из примеров выше.



    Функция для удаления файла


    Ну и в конце функция удаления файла.


  • Скрипт функции:


  • # Функция для удаления файла
    func del_f(name: String):
    var dir = Directory.new()
    if dir.remove(name) == OK:
    return "1"
    else:
    return "0"

    Эта функция полезна во-многих аспектах работы с файлами.
    Удаление сохранений, удаление профилей и т.д.
    В общем, любых файлов.


  • Пример вызова:


  • # Удаляем профиль игрока
    var profil_f = "user://gamer.cfd"
    var result = fm.del_f(profil_f)
    print(result) # Выведет "1" при успешном удалении строки

    Все необходимые и основные функции для работы с файлами перечислены.
    Но ниже, хочу представить универсальный подход к работе из одного скрипта, что упростит множество задач и повысит продуктивность!



    Полный скрипт для работы с функциями!


    Ниже я даю скрипт файла sl_file.gd в котором собраны все вышеупомянутые функции для того, что-бы не переписывать их постоянно в ваших скриптах.


  • Скрипт файла sl_file.gd


  • extends Node

    # Функция для создания нового файла
    func new_f(name: String, text_n: String):
    var file = File.new()
    # Открываем файл для записи, если файл не существует, он будет создан
    if file.open(name, File.WRITE) == OK:
    file.store_line(text_n) # Записываем строку в файл
    file.close() # Закрываем файл
    return "1"
    else:
    return "0"

    # Функция для чтения всего файла
    func read_all_f(name: String):
    var profil_f = "user://gamer.cfd"
    if File.new().file_exists(name):
    #print("Файл существует!")
    var file = File.new() # Создаём объект файла
    file.open(name, File.READ) # Открываем файл для чтения
    var line = file.get_as_text()
    file.close() # Закрываем файл
    return line
    else:
    return "0"

    # Функция для чтения определённых, нескольких строк с загрузкой всего файла
    func read_all_str_f(name: String, line_nums: String):
    if File.new().file_exists(name):
    var file = File.new()
    file.open(name, File.READ)

    var lines = file.get_as_text().split("\n") # Читаем весь файл и разбиваем на строки
    file.close()

    var indices = line_nums.split(":") # Разбиваем строку параметров "1:3:5" на список
    var result = []

    for index in indices:
    var line_index = int(index) - 1 # Преобразуем строку в число и сдвигаем на -1 (чтобы начиналось с 0)
    if line_index >= 0 and line_index < lines.size():
    result.append(lines[line_index])
    else:
    result.append("0") # Если строки нет, добавляем "0"

    return ":".join(result) # Возвращаем результат в виде строки через ":"
    else:
    return "0"

    # Функция для чтения определённой строки
    func read_str_f(name: String, line_num: int):
    if File.new().file_exists(name):
    var file = File.new()
    file.open(name, File.READ)

    var line = ""
    for i in range(line_num): # Читаем строки до нужной
    if file.eof_reached(): # Проверяем, не закончился ли файл раньше
    file.close()
    return "0"
    line = file.get_line()

    file.close()
    return line
    else:
    return "0"

    #Функция для записи данных в файл
    func dop_f(name: String, text_n: String, mode: int):
    var file = File.new()
    # Проверяем существование файла
    var file_exists = file.file_exists(name)
    # Открываем файл в нужном режиме
    if file.open(name, File.WRITE_READ) == OK:
    if mode == 1 and file_exists:
    # Читаем старое содержимое
    var old_content = file.get_as_text()
    file.seek(0) # Перемещаем курсор в начало
    file.store_string(text_n + "\n" + old_content) # Записываем новый текст + старое содержимое
    elif mode == 2:
    file.seek_end() # Перемещаем курсор в конец
    file.store_line(text_n) # Добавляем строку в конец
    else:
    file.store_line(text_n) # Если файла не было, просто создаём и пишем строку
    file.close()
    return "1"
    else:
    return "0"

    # Функция для обновления всего файла
    func upd_f(name: String, new_text: String):
    var file = File.new()
    # Открываем файл в режиме WRITE (очищает старое содержимое)
    if file.open(name, File.WRITE) == OK:
    file.store_string(new_text) # Записываем новые данные
    file.close()
    return "1"
    else:
    return "0"


    # Функция для обновления определённой строки
    func upd_str_f(name: String, line_num: int, text: String):
    var file = File.new()
    # Проверяем, существует ли файл
    if not file.file_exists(name):
    return "0"
    # Открываем файл для чтения
    if file.open(name, File.READ) != OK:
    return "0"
    var lines = file.get_as_text().split("\n") # Читаем все строки
    file.close()
    # Проверяем, что номер строки в допустимых пределах
    if line_num < 1 or line_num > lines.size():
    return "0"
    lines[line_num - 1] = text # Обновляем нужную строку (нумерация с 0)
    # Перезаписываем файл с обновлёнными строками
    if file.open(name, File.WRITE) == OK:
    file.store_string("\n".join(lines)) # Записываем новый текст
    file.close()
    return "1"
    else:
    return "0"

    # Функция для обновления части строки (с beg до end)
    func upd_part_str_f(name: String, line_num: int, beg: int, end: int, text: String):
    var file = File.new()
    # Проверяем, существует ли файл
    if not file.file_exists(name):
    return "0"
    # Открываем файл для чтения
    if file.open(name, File.READ) != OK:
    return "0"
    var lines = file.get_as_text().split("\n") # Читаем все строки
    file.close()
    # Проверяем, что номер строки в допустимых пределах
    if line_num < 1 or line_num > lines.size():
    return "0"
    var line = lines[line_num - 1] # Получаем нужную строку (нумерация с 0)
    # Проверяем, что индексы находятся в пределах строки
    if beg < 0 or beg >= line.length() or end < beg or end > line.length():
    return "0"
    # Обновляем только нужную часть строки
    lines[line_num - 1] = line.substr(0, beg) + text + line.substr(end)
    # Перезаписываем файл с обновлёнными строками
    if file.open(name, File.WRITE) == OK:
    file.store_string("\n".join(lines)) # Записываем новый текст
    file.close()
    return "1"
    else:
    return "0"

    # Чтение части строки в файле
    func read_part_str_f(name: String, line_num: int, beg: int, end: int) -> String:
    var file = File.new()
    # Проверяем, существует ли файл
    if not file.file_exists(name):
    return "0"
    # Открываем файл для чтения
    if file.open(name, File.READ) != OK:
    return "0"
    var lines = file.get_as_text().split("\n") # Читаем все строки
    file.close()
    # Проверяем, что строка существует
    if line_num < 1 or line_num > lines.size():
    return "0"
    var line = lines[line_num - 1] # Получаем нужную строку (нумерация с 0)
    # Проверяем, что индексы находятся в пределах строки
    if beg < 0 or beg >= line.length() or end < beg or end > line.length():
    return "0"
    # Возвращаем часть строки
    return line.substr(beg, end - beg)

    # Функция для удаления строки из файла
    func del_str_f(name: String, line_num: int):
    var file = File.new()
    # Проверяем, существует ли файл
    if not file.file_exists(name):
    return "0"
    # Открываем файл для чтения
    if file.open(name, File.READ) != OK:
    return "0"
    var lines = file.get_as_text().split("\n") # Читаем все строки
    file.close()
    # Проверяем, что номер строки в допустимых пределах
    if line_num < 1 or line_num > lines.size():
    return "0"
    # Удаляем нужную строку
    lines.remove(line_num - 1) # Нумерация с 0, поэтому уменьшаем на 1
    # Перезаписываем файл без удалённой строки
    if file.open(name, File.WRITE) == OK:
    file.store_string("\n".join(lines)) # Записываем новый текст
    file.close()
    return "1"
    else:
    return "0"

    # Функция для удаления файла
    func del_f(name: String):
    var dir = Directory.new()
    if dir.remove(name) == OK:
    return "1"
    else:
    return "0"


    Далее, я привожу все вышеупомянутые примеры вызовов функций, но уже намного универсальнее, так как они будут записаны всего один раз в одном файле и вам ненужно их переписывать снова и снова в разных скриптах сцен.


  • Примеры вызова с подключённым скриптом sl_file.gd


  • extends Node

    var profil_f = "user://gamer.cfd"

    # Для начала, подключаем файл с функциями к любому скрипту
    # У меня в этом примере, этот файл находится в папке совсеми скриптами res://script
    # Подгружаем скрипт и создаём экземпляр только когда нужно
    var fm = preload("res://script/sl_file.gd").new()

    # Далее, я буду вызывать эти функции по нажатию кнопки
    # Обратите внимание, что во всех примерах будет каждый раз задействована одна и та же кнопка!

    # Cоздание файла.
    func _on_Button_pressed():
    var result = fm.new_f("user://gamer.cfd", "Name")
    print(result)

    # Чтение всего файла
    func _on_Button_pressed():
    var result = fm.read_all_f(text_log)
    print(result)

    # Чтение нескольких строк из файла
    func _on_Button_pressed():
    var result = fm.read_all_str_f("user://gamer.cfd", "1:3")
    print(result)

    # Функция для чтения определённой строки
    func _on_Button_pressed():
    var result = fm.get_line_number(profil_f, 5)
    print(result)

    # Функция для записи данных в файл
    func _on_Button_pressed():
    var result = fm.new_f(profil_f, "Добавлено в начало", 1)
    print(result)

    # Обновляем весь файл
    func _on_Button_pressed():
    var result = fm.update_f(profil_f, "Это новый текст файла")
    print(result)

    # Обновляем строку
    func _on_Button_pressed():
    var result = fm.upd_str_f(profil_f, 2, "Обновлённая строка")
    print(result)

    # Обновляем часть данных
    func _on_Button_pressed():
    var result = fm.upd_part_str_f(profil_f, 2, 28, 30, "085")
    print(result)

    # Читаем часть данных
    func _on_Button_pressed():
    var result = fm.read_part_str_f(profil_f, 2, 28, 30)
    print(result)

    # Удаление строки
    func _on_Button_pressed():
    var result = fm.del_str_f(profil_f, 2)
    print(result)

    # Удаление файла
    func _on_Button_pressed():
    var result = fm.del_f(profil_f)
    print(result) # Выведет "1" при успешном удалении строки



    Заключение публикации


    И так, в заключении хочу сказать, что многие опытные программисты могут сказать,
    "А почему не сделать один вызов с флагом для всех этих функций?"
    или
    "Почему нет более детального вывода ошибок?"
    да в общем, много может быть вопросов и предложений, я это понимаю!

    Конечно же, можно усовершенствовать всё до бесконечности. Но в данном варианте представленно всё максимально просто и минимизировано. Главное, что это просто и оно работает!



    В добавок хочу сказать, что это не коммерческий код и всем он доступен абсолютно свободно и бесплатно!



    В остальном, изучайте, улучшайте, пробуйте внедрять что-то новое и т.д.



    Так же, вы можете переименовывать функции как вам удобнее, так как я именовал их для себя.
    Главное помните, что GDscript регистрозависимый!

    То есть!
    К примеру:
    Это



    var line = fm.read_all_f("user://Gamer.cfd")

    и это



    var line = fm.Read_all_f("user://gamer.cfd")

    два вызова абсолютно разных функций с именами абсолютно разных файлов!
    В Windows может и работать так как для Windows, это Gamer.cfd и это gamer.cfd один и тот же файл, а вот в Linux и Android точно не будет, так как это Gamer.cfd и это gamer.cfd для них разные файлы, так как они регистрозависимые