Как в lua указать путь к файлу

Обновлено: 25.06.2024

Таблицы в целом — самый важный тип данны в Lua.

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

Самый простой массив выглядит так:

«Заполнять» массивы можно так:

После последнего элемента запятая не обязательна.

Индексация массивов — это следующий параграф.

§14.1.1. Индексация массивов.

Индексация массивов в Lua начинается не с нуля, как в некоторых других языках (в том же C), а с единицы.

Полностью эквивалентна этой:

Подобная индексация нежелательна:

Почему? Это следующий параграф.

Но если надо, можно так:

§14.1.2. Определение длины массива.

Вот простой пример:

Чтобы не было проблем с версиями Lua, дальше уже будет писаться только table.getn().

Здесь напечатается 3, поскольку в массиве три элемента.

А что напечатается здесь?:

А напечатается здесь 1, поскольку индекс два равен nil.

А тут вовсе напечатается 0:

Поскольку индекс один равен nil.

Потому что тут вообще ошибка вылезет.

В общем, чтобы оператор длины работал корректно, нужно указывать все индексы правильно, или не указывать вообще, — Lua это сам сделает.

§14.1.3. Обращение к элементам массива.

Обращение к элементам массива происходит так:

Пишется название массива, затем в квадратных скобках указывается его индекс.

§14.1.4. Цикл обхода всех элементов массива.

Вот, собственно, один из двух циклов, упомянутый в §10.5.

Для обхода всех элементов массива используется расширенный арифметический цикл for вместе с переменной ipairs.

То, что перед запятой, — индекс массива, а после — его значение (для примера ниже значение первого индекса — "one").

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

Иногда в получении индекса либо значения нет необходимости, в таком случае, переменная заменяется на подчёркивание:

§14.1.4.1. Обход элементов массива иными способами.

Для обхода все элементов можно и не пользоваться ipairs и for .. in, а просто воспользоваться арифметическим for и оператором длины:

В качестве индекса используется, как понятно, переменная i.

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

А вот может случиться такая ситуация, что нескольким (но не всем) элементам массива необходимо будет присвоить одно и то же значение. Можно, конечно, воспользоваться примитивными методами, типа:

И так далее. Но намного быстрее воспользоваться арифметическим for:

Для всех элементов можно по стандарту:

for i,_ in ipairs(m) do
m[i] = nil;
end

Тут уже кому как.

§14.1.5. Массивы внутри массивов.

Если есть необходимость в этом, внутри пары фигурных скобок создаётся ещё одна пара (просто фигурные скобки, без названия), и туда как обычно записываются элементы нового массива.

Обращение к элементам массива, который внутри другого массива, происходит так: сначала в квадратных скобках пишется индекс внешнего массива, в котором расположен внутренний, затем уже так же индекс элемента внутреннего массива:

Обход такого массива выглядит так:

Так можно создавать огромное количество массивов, каждый из которых будет внутри предыдущего:

Таблицы — это набор пар «ключ — значение». Конструкция такая же, как и у массивов.

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

Как уже было сказано выше, значением таблиц могут быть и числа, и булевые значения (true, false), и функции, и строки, и таблицы, и массивы, и даже nil.
Для отделения типов данных друг от друга будет удобно использовать точку с запятой вместо обычной запятой:

t = <
number1 = 1,
number2 = 2;
str = "string";
t2 = <
n = 4;
n1 = true;
>;
m = ;
jj = false,
gg = true;
wtf = nil;
>;

§14.2.1. Обращение к элементам таблицы.

Почти всегда обращение выглядит так:

Когда в таблице таблица, обращение происходит так:

Когда в таблице массив, обращаться можно так:

Ну и понятно, что если в таблице есть массив, внутри которого массив, обращаться можно так:

Для таблиц понятия «длина» как такового нет, так что использовать соответствующего оператора для таблиц нельзя.

§14.2.2. Цикл обхода элементов таблицы.

Что это — обьяснять не надо. Для обхода элементов таблицы используется pairs, вместо ipairs. И обычно вместо переменной i (index) используется k (key) (но можно, естественно, писать свои названия).

Есть таблица со списком оружия и его уроном в процентах. Надо присвоить всему оружия нулевой урон:

Weapons = <
Knife = 20,
Pistol = 40,
ShotGun = 80,
AssaultRifle = 85,
SniperRifle = 95,
MiniGun = 100,
RocketLauncher = 110,
>;

§14.2.3. Функции в таблицах.

Сразу создать функцию в таблице, похоже нельзя. Но если такое необходимо, это можно сделать следующим образом:

§14.3. Функции для работы с таблицами.

Все они начинаются с «table.» (от англ. «table» — ‘таблица’). Вот все они:

table.concat(table [, sep [, i [, j]]]):

Задан массив, в котором все элементы — строки или числа, возвращает table[i]..sep..table[i+1] ··· sep..table[j]. Значение по умолчанию для sep — пустая строка, значение по умолчанию для i — 1, а для j — длина таблицы.
Если i больше j, функция возвращает пустую строку.

table.insert(table, [pos,] value):

Вставляет элемент value в позицию pos в table, сдвигая вверх остальные элементы. Значение по умолчанию для pos равно n+1, где n — длина таблицы, т. о., вызов table.insert(t,x) добавляет x в конец таблицы t.
Только для массивов.

Удаляет из table элемент в позиции pos, сдвигая вниз остальные элементы, если это необходимо. Возвращает значение удаленного элемента. Значение по умолчанию для pos — n, где n — длина таблицы, т. о.,
вызов table.remove(t) удаляет последний элементы таблицы t. (Примечание: использование insert-remove со значениями по умолчанию позволяет работать с таблицей как со стандартным LIFO – стеком) Только для массивов.

Сортирует элементы таблицы в заданном порядке внутри таблицы, начиная с table[1] и заканчивая table[n], где n — длина таблицы. Если параметр comp задан, то он должен быть функцией,
которая для двух получаемых параметров возвращает true, если первый из них меньше второго (т. о., not comp(a[i+1],a[i]) будет верно для любого i давать true после окончания сортировки).
Если comp не задан, то вместо него будет использован стандартынй оператор Lua «<».

Алгоритм сортировки не стабилен; в том смысле, что равные элементы могут быть переставлены в процессе сортировки.

Также ещё существуют такие полезные функции для массивов:

Возвращает следующей индекс массива после указанного и соответствующее ему значение.

Возвращает либо все значения массива, либо от одного индекса и до другого.

Возвращает значение указанного индекса массива.

Вместо этого можно просто написать так:

Присваивает указанному индексу массива новое указанное значение.

Вместо этого можно просто написать так:

Все эти функции начинаются с «io.» (сокр. от англ. «input-output» — ‘ввод-вывод’). Главное применение — изменение внутреннего содержания файла непросредственно из Lua-скрипта.
Вот четыре функции, которые понадобятся для этого:

Открывает файл по указанному пути в указанном режиме. Режимов всего три:
«r» — режим чтения. Данный режим используется как режим по умолчанию. То есть, если не указать режим, файл откроется в данном режиме;
«w» — режим записи. Вся имеющаяся ранее информация стирается;
«a» — режим дозаписи в конец файла. Вся имеющаяся ранее информация сохраняется.
Путь в свою очередь пишется в кавычках; название файла обязательно должно иметь расширение. Если в указанной директории не существует такого файла, он будет создан.

Записывает в указанный файл указанные значения. Ими должны быть только строки, числа и управляющие последовательности. file — переменная, открывающая файл (ниже всё станет понятно).

Сохраняет сделанные изменения в указанном файле.

Закрывает указанный файл.

Нужно дописать в конец файла script.lua, расположенного в папке data, несколько строк:

-- создаём массив из строк, которые необходимо добавить в конец нашего файла
local ns = <
"string1",
"string2",
"string3",
"string4",
"string5",
>;

После открытия файла в конце будет следующее:

string1
string2
string3
string4
string5

§15.1. Ещё несколько полезных функций.

Открывает указанный файл в режиме чтения, считывает из него все имеющиеся в нём в строке и возвращает каждую отдельно.

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

То же, что и io.lines, но не закрывает файл file после окончания цикла.

Получает и выставляет в файле позицию, заданную первым аргументом, им может быть:

"set" — начало файла;
"cur" — текущая позиция;
"end" — конец файла.

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

Все эти функции начинаются с «os.» (сокр. от англ. «operation system» — ‘операционная система’) Вот некоторые из них:

Возвращает примерное количество времени (в секундах), которое программа выполнялась на CPU.

Возвращает дату, отформатированную в соответствии с заданным форматом.
Если аргумент time передается функции, то должно быть отформатировано «время» (os.time). В противном случае, параметр date используется для форматирования текущего времени.
Если параметр format начинается с «!», то время форматируется в соответствии с универсальным глобальным временем (по Гринвичу). После этого опционального символа, если format равен «*t», то date возвращает таблицу
со следующими полями: year (год, четыре цифры), month (месяц, 1—12), day (день, 1—31), hour (час, 0—23), min (минуты, 0—59), sec (секунды, 0—61), wday (день недели, воскресенью соответствует 1 и так адлее), yday (день года),
и isdst (флаг дневного времени суток, тип boolean).
Если format не равен «*t», то функция date возвращает дату в виде строки, отформатированной в соответствии с правилами функции C strftime.
При вызове без аргументов возвращают дату, во время которой была вызвана данная функция, в соответствии с установленными датой и временем оперционной системы, в следующем формате: MM/DD/YYYY HH:MM:SS.

Возвращает время, прошедшее от первого аргумента до второго, в секундах. На самом деле функция просто возвращает значение первого аргумента минус значение второго аргумента.

Мне интересно, есть ли способ получить путь к исполняемому в данный момент файлу сценария lua?

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

РЕДАКТИРОВАТЬ: Я не использую стандартный интерпретатор командной строки, я выполняю сценарии из двоичного файла C ++ через luabind.

Если сценарий Lua запускается стандартным интерпретатором командной строки, попробуйте arg[0] .

Если он возвращает ноль, попробуйте изменить .\*\\\ на .*/ и arg[0] на debug.getinfo(1).short_src .

Но я считаю, что это лучший и самый короткий способ получить текущий каталог.

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

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

Проверено на Windows.

Объяснение:

io.popen - отправляет команды в командную строку и возвращает результат.

"cd" - когда вы вводите это в cmd , вы получаете текущий путь в качестве вывода.

:read'*all' - поскольку io.popen возвращает объект в виде файла, вы можете прочитать его с помощью тех же команд. Это читает весь вывод.

Если кому-то требуется UNC-путь:

Если вам нужен фактический путь:

Иначе используйте это для полного пути к файлу:

Взгляните на библиотеку отладки Lua, которая является частью стандартного дистрибутива Lua. Вы можете использовать debug.getinfo для поиска текущего файла или файла до N кадров в стеке вызовов:

Обратите внимание, что это, вероятно, довольно медленно, так что это не то, что вы хотите делать на быстром пути, если вас беспокоят такие вещи.

Я написал функцию getScriptDir , которая использует отладочную информацию, как предлагали некоторые другие люди, но эта функция будет работать каждый раз (по крайней мере, в Windows). Но дело в том, что существует довольно много строк кода, поскольку он использует другую функцию string.cut , которую я создал, которая разделяет строку по каждому заданному шаблону и помещает ее в таблицу.

Примечание: если вы хотите использовать эту функцию в другой ОС, кроме Windows, вам нужно изменить io.popen("echo %cd%") в строке 15 на любую команду, которая дает вам настоящую работу. каталог в вашей ОС, например io.popen("pwd") для Linux и pwd2:sub(2,3) == ":/" в строке 18 для того, что представляет корневой каталог в вашей ОС, например pwd2:sub(1,1) == "/" для Linux.

Примечание 2: если вы не предоставите переменную source функции через debug.getinfo(1).source при ее вызове, она вернет путь к каталогу файла . содержащий эту функцию . Следовательно, если вы хотите получить каталог файла, который вы вызвали через dofile или loadfile , вам придется указать ему источник, например: getScriptDir(debug.getinfo(1).source) .

Единственный надежный способ получить желаемое - заменить dofile вашей собственной версией этой функции. Даже метод debug.getinfo не будет работать, потому что он вернет только строку, переданную в dofile . Если это был относительный путь, он не знает, как он был преобразован в абсолютный путь.

Код переопределения будет выглядеть примерно так:

Функции extractFilePath , isRelativePath и currentDir не являются функциями Lua; вам придется написать их самостоятельно. Функция extractFilePath извлекает строку пути из имени файла. isRelativePath берет путь и возвращает, является ли данный путь относительным путем. currentDir просто возвращает текущий каталог. Кроме того, вам нужно будет использовать «\» вместо «/» на компьютерах с Windows.

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

Самая короткая форма, которую я нашел, выглядит так:

Индекс 1, 2 - другое - зависит от того, какую функцию в стеке вызовов вы хотите запросить. 1 - последняя вызываемая функция (где вы находитесь). Если вы работаете в глобальном контексте, то, вероятно, 2 будет более подходящим (не тестировал сам)

Библиотека пакетов Lua предоставляет простой способ загрузки и создания модулей для Lua. require метод module Методы и package Состав стола .

Начиная с Lua5.1, добавлена ​​новая поддержка модулей и пакетов, которые можно использовать module с участием require Для определения и использования модулей и пакетов. В Lua модуль - это «первый тип значения», а модуль - это программная библиотека. require(module) Чтобы получить глобальный table Переменная, это table Подобно пространству имен, его содержимым является все, что экспортируется в модуль, например, функции и переменные.

module

Исходное поведение, определяемое модулем:

Lua5.1 предоставляет новые функции module() , Таблица будет создана и назначена глобальным переменным и loaded table , И, наконец, установите эту таблицу в качестве среды основного блока программы.

по умолчанию, module Внешний доступ не предоставляется, и соответствующие локальные переменные должны быть объявлены для внешней функции или модуля, к которым необходимо получить доступ до вызова. Вы также можете получить внешний доступ через наследование, просто позвонив module Добавить когда package.seeall Параметры.

Процесс обработки модуля

  1. в случае package.loaded[module_name] Является table , Тогда это table как module 。
  2. Если глобальная переменная module_name Является table , Рассматривать глобальную переменную как module 。
  3. В двух текущих случаях таблицы нет module_name , Создадим новый table И сделайте это глобальным именем module_name Ценить и выполнять package.loaded[module_name] .
  4. Вызов функции обратного вызова по очереди
  5. Установите для среды текущего модуля значение module В то же время package.loaded[module_name] = module

от module() Вы можете легко написать содержание модуля, module После выполнения инструкции вся среда помещается в стек, в результате чего предыдущие глобальные данные больше не отображаются.

от module("module_name", package.seeall) Явно объявить пакет, но официально этот метод не рекомендуется, потому что:

  • package.seeall Путь разрушает высокую связность модуля, изначально введенного old_module Укажите на звонящего foo() Функция, но она может читать и записывать глобальные свойства, такие как old_module.os 。
  • module Функциональный side-effect , Будет загрязнять глобальные переменные среды.

Итак, еще пройти return table Более элегантно реализовывать модули.

Иногда необходимо переименовать модуль, чтобы избежать конфликтов имен. Например, в тесте необходимо загрузить разные версии одного и того же модуля, чтобы получить разницу в производительности между версиями. Как загрузить разные версии одного и того же модуля? Для файла Lua его можно легко переименовать. Но для библиотеки C редактировать ее нельзя. luaopen_* Имя функции.

Чтобы переименовать заявку, require Используется уловка: если в названии модуля есть дефис, require Будет использовать содержимое с дефисами для создания luaopen_* Имя функции. Таким образом можно легко решить необходимость тестирования различных версий.

Самый простой способ создать модуль в Lua - создать table И поместите в него все функции, которые нужно экспортировать, и, наконец, верните это table 。

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

Дефект: модуль фактически использует локальную переменную, которая проста и грубовата. Функции в модуле по-прежнему нуждаются в префиксе. Как избежать написания имени модуля полностью?
Идея: удалите префикс и, наконец, назначьте локальную переменную имени модуля.

  • . Функция заключается в том, что вам вообще не нужно определять имя модуля в модуле. Если вам нужно переименовать модуль, вам нужно только переименовать файл, который его определяет.
  • return При определении модуля return Это очень упущение для написания.Можно ли сконцентрировать все задачи настройки модуля в начале модуля?

Идея: исключить return

  • Устранить return Метод заключается в добавлении модуля table Назначить напрямую package.loaded Может
  • require Имя модуля будет передано в модуль как параметр, то есть нет return Имя модуля, потому что, если модуль не имеет возвращаемого значения,
  • require Вернется package.loaded[module] Текущее значение.

package.loaded Что тогда? require Сохранит возвращаемое значение в package.loaded из table Средний, если загрузчик loader Нет возвращаемого значения, require Вернется package.loaded в table Значение.

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

Идея: эта проблема может быть решена с помощью «функциональной среды», так что главный программный блок модуля может иметь эксклюзивную среду, так что не только все его функции могут разделять это table , И все его глобальные переменные также записываются в эту table , Вы также можете объявить все функции как глобальные переменные. Таким образом, они автоматически записываются в отдельный table в. Модуль должен добавить это table Дайте название модуля и package.loaded 。

Дефект: При звонке setfenv После этого поставить пустой table из M Как среда, вы не можете получить доступ к глобальным переменным в предыдущей среде.
Идея 1. Самый простой способ - использовать метатаблицу, задав __index , Смоделировать наследование для достижения.

Дефект: настройка мета-таблицы требует дополнительных затрат.
Идея 2. Использование локальных переменных для сохранения глобальных переменных среды. При доступе к переменным в предыдущей среде необходимо добавить префикс. _G , Поскольку мета-метод не используется, этот метод немного быстрее, чем первый метод.

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

Таким образом, шаги для определения модуля следующие:

  1. Из require Получите имя модуля из входящих параметров
  1. Создать пустой table
  1. В глобальной среде _G Добавьте поле, соответствующее названию модуля, в table Присвойте значение этому полю.
  1. Уже загружено table Установите модуль в
  1. Установить переменные среды

Чтобы упростить работу, Lua5.1 + предоставляет module() Функция, которая содержит функции, выполненные на вышеуказанных шагах, напрямую заменяет указанные выше операции при написании модуля.

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

require

require() Сначала функция package.loaded Он есть в таблице module_name , Если он существует, вернуть значение напрямую, если не существует, загрузить его через определенный загрузчик module_name 。

Начиная с Lua5.1 +, Lua использует стандартную библиотеку управления модулями, и все модули загружаются через require() осуществлять. require() Дизайн достаточно расширяемый, он будет начинаться с нескольких определенных loader Попробуйте загружать новые модули по одному. Предоставьте 4 в системной библиотеке loader , Соответственно реализовать загруженный модуль, модуль Lua и модуль расширения C. Вот эти loader Чтобы CFunction В виде require Одно из окружения table в. Если вы хотите изменить метод загрузки модуля Lua, просто замените или добавьте новый loader Вот и все.

require Процесс внедрения

  1. в package.loaded Найти в module_name
  1. в package.preload Найти в module_name Если preload Существовать как loader И позвони loader(L)
  2. в соответствии с package.path Найдите файлы Lua

package.path Сохраните и загрузите путь поиска внешних модулей, этот путь является «путем к шаблону», путь будет содержать заменяемые символы ? , Этот символ будет заменен, и Lua будет искать наличие этого файла, если он существует, он вызовет определенный интерфейс.

package.path Устанавливается при запуске виртуальной машины, если есть переменные среды LUA_PATH Используйте переменную среды в качестве значения и установите ;; Заменить luaconf.h Значение по умолчанию, определенное в, если переменная не существует, она будет использоваться напрямую luaconf.h Определенное значение по умолчанию.

  1. в соответствии с packkage.cpath Найдите библиотеку C и вызовите интерфейс с соответствующим именем.

package.cpath А также package.path То же самое, но он используется для загрузки сторонней библиотеки C, а его начальное значение может быть передано в переменные среды LUA_CPATH Установить.

package.loadlib(libname, func) Эквивалентно открытию библиотеки C вручную libname И экспортируем функцию func Вернуться позднее, loadlib Фактически ll_loadlib 。

Как Lua находит модули?

Чтобы загрузить модуль, вы должны знать, где он находится. Платформа Windows будет искать по переменной среды Path, require Используемый путь отличается от традиционного пути.Используемый путь представляет собой серию шаблонов, каждый из которых является способом преобразования имени модуля в имя файла. requie Будет использовать имя модуля для замены ? . Затем проверьте, существует ли файл по результату замены, если его нет, попробуйте следующий пункт. Каждый элемент в пути разделяется точкой с запятой. require Только иметь дело с ; с участием ? , А все остальное определяется самим путем.

require Путь - это список шаблонов, используйте предоставленный для require Чтобы заменить вопросительный знак в шаблоне на имя виртуального файла и определить, существует ли файл, в противном случае используйте второй шаблон, чтобы попытаться сопоставить. для того, чтобы require Чтобы найти модуль Lua, который вы написали, вам нужно добавить путь к модулю в LUA_PATH В LuaStudio есть package.path 。

Есть один в Lua table Используется для сохранения списка всех загруженных файлов, в LuaStudio это package.loaded . Может быть просмотрен package.loaded Существует ли в таблице имя загружаемого файла, чтобы определить, был ли он загружен.

В реальном программировании require Путь к файлу Lua, который используется для поиска, хранится в переменной package.path в. Когда Lua запускается, он использует переменную окружения LUA_PATH Чтобы инициализировать переменную package.path . Если не LUA_PATH Используйте для инициализации путь по умолчанию, определенный во время компиляции.

Каким образом требуются модули загрузки функций?

  • Первая проверка package.loaded Был ли он загружен.
  • Если require Найдите файл Lua для указанного модуля, он пройдет loadfile Загрузить файл.
  • Если require Если файл Lua, соответствующий имени шаблона, не может быть найден, будет произведен поиск библиотеки C, и адрес поиска будет package.cpath Соответствующий путь.
  • Если он найдет библиотеку C, передайте loadlib Загружать.

обрати внимание на loadfile с участием loadlib Он просто загружает код, но не запускает его. Чтобы запустить код, require Код вызывается с именем модуля в качестве параметра.

require & dofile & loadfile

Lua предоставляет require() Функция используется для загрузки библиотеки времени выполнения, require() с участием dofile() Выполните ту же функцию, разница в


Пример работы с файлами в QLua (Lua): 131 комментарий

Каким способом можно удалить файл?

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

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

Здравствуйте. Скажите, есть ли функция, чтобы удостоверится, что файл уже открыт другим процессом ( ботом)? Т.е. хочу в один файл писать из разных роботов и чтобы не было конфликта, что бы робот "ждал" пока другой закончил чтение/запись и закрыл файл. Вроде, это что-то простое должно быть?

Файл открывается у меня для чтения local f = io.open(path, "r+")
Файл открывается у меня для записи local f = io.output(path)
Правда я не проверял, может уже будет "конфликт" и можно его "зафиксировать" и ждать.

только обрабатывая ошибки открытия файла. примерно так:

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

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

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

f = io.open(getScriptPath().."\\Test.txt","r+");
и почему в конце , "r+", что оно делает? И для чего нужна

f = io.open(getScriptPath().."\\Test.txt","r+");
Не могли бы Вы объеснить чуть краче , тоесть , что такое getScriptPath()..""\\

"и почему в конце , "r+", что оно делает? И для чего нужна" - это режим открытия файла r от слова read - чтение, знак + означает что можно еще и писать будет в файл, в итоге "r+" означает режим чтения/записи

"Не могли бы Вы объеснить чуть краче , тоесть , что такое getScriptPath()..""\\" - getScriptPath() это функция встроенная в QLua, которая возвращает полный путь к скрипту, из которого она вызвана, оператор ".." называется оператором конкатенации, т.е. служит для склеивания нескольких строк в одну. В итоге, если Ваш скрипт находится в папке "C:\\Trading", то в результате склейки получится строка "C:\\Trading\\Test.txt", двойной слеш используется для экранирования символа слеш, т.к. есть различные спецсимволы, которые содержат в себе слеш, например, "\n" означает перенос строки, и чтобы в строку добавить именно символ слеш, который компьютер не будет пытаться распознать как начало спецсимвола, нужно экранировать его вторым слешем.

Такой вопрос. Если я "поставил" курсор в нужное место, то я могу как-то "вставлять" или наоборот "затирать"?
Например, есть строка в файле : "Я иду в школу", "ставлю" курсор перед "школу" . Если я в это место впишу "любимую" , то получится: "Я иду в любимую" правильно? Т.е. школа затрется? А можно "вставить" чтобы получилось ". в любимую школу". Или запись в файл как раз наоборот работает - вставляет , а не затирает? Или может даже есть разные способы? Понятно что можно считать весь файл и работать уже с текстом и потом полностью перезаписать. А вот сразу в файл так нельзя писать в разных режимах?

Только перезаписывать поверх можно, вставлять нельзя, файл это область памяти выделенная, к ней можно только добавить в конец еще какой-то объем памяти. Это как строка в тетради написанная, Вы же не сможете внутрь нее еще слов вставить, только перезаписать поверх, или в конец добавить. С файлами так же.

Здравствуйте!
Подскажите а как из файла прочитать данные в переменную.
Спасибо!

День добрый.
как получить значение из последней строки в txt файле?
как получить значение из последний строки предпоследнего столбца в файле csv, или например 3 столбца?

Добрый день!
Данный скрипт

Ошибка lua:6: attempt to index global 'f' (a nil value)
Помогите разобраться!

Видно, что недостаточно базовых знаний по программированию, приглашаю на скайп-обучение 🙂

Читайте также:

[module name="footer"]