1 (2014-08-24 13:55:09 отредактировано swerg)

Тема: Передача данных из Lua-скрипта в другую программу через файл

Вопрос был задан на форуме QUIK:

В скрипте lua происходит выгрузка данных в файл:
f=io.open(getScriptPath().."\\Sr\\".."Treids.txt","w")
f:write("sell")
f:close()
При обращении внешнего приложения на Delphi возникает ошибка - "файл занят другим процессом".
Вопрос - есть у кого-нибудь мысли по поводу того почему так происходит?

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

list:=TStringList.Create;
appdir:= ExtractFileDir(ParamStr(0));
str:=(appdir+'\Files\Rts\Stop.txt');
list.LoadFromFile(str);
//операции с данными
list.free;

Беда методе list.LoadFromFile(). Если посмотреть его исходники, то видно, что файл открывается просто на чтение, без указания доп. опций "чтения с общим доступом".

2 (2014-08-24 13:55:52 отредактировано swerg)

Re: Передача данных из Lua-скрипта в другую программу через файл

Для экспериментов сделал такой Lua-файл:

function OnInit()
  out_file = io.open(getScriptPath().."\\".."ex_file.txt","w")
  is_run = (out_file ~= nil)
end

function main()
  local i = 0
  while is_run do
    out_file:write("i=" .. tostring(i) .. "\n")
    out_file:flush()
    sleep(500)
    i = i + 1
  end
  out_file:close()
end

function OnStop()
  is_run = false
end

Создает в иректории со скриптом файл ex_file.txt и пишет в него строки вида

i=0
i=1
i=2

и т.д.

3 (2014-08-26 11:05:11 отредактировано swerg)

Re: Передача данных из Lua-скрипта в другую программу через файл

Как сделать чтение такого файла при работающем Lua-скрипте.

Delphi

Для чтения файла будем использовать объект класса TFileStream, в методе Create которого последним параметром можно указать тип доступа к файлу. В нашем случае надо указать два модификатора: fmOpenRead и fmShareDenyNone
Ниже приведен фрагмент кода, функционально аналогичный тому, что дан в первом посте. Здесь загружается файл в объект типа TStringList:

const
    FILE_NAME = 'D:\QUIK\Lua\ex_file.txt';
var
    List: TStringList;
    Stream: TStream;
begin
    if FileExists(FILE_NAME) then
      begin
        List := TStringList.Create;
        try
          Stream := TFileStream.Create(FILE_NAME, fmOpenRead or fmShareDenyNone);
          try
            List.LoadFromStream(Stream);
          finally
            Stream.Free;
          end;
          //
          // ... здесь обработка строк из файла, которые находятся в List ...
          //
          Memo1.Lines.Assign(List);
        finally
          List.Free;
        end;
      end;
end;

В общем архиве со всеми примерами (ссылка в следующем сообщении) приведен пример чтения файла и отображение его содержимого в TMemo в окне программы. Содержимое TMemo постоянно обновляется (используется таймер).
Т.к. TMemo имеет готовое свойство Lines типа TStrings, то отдельный экземпляр TStringList не создается, чтение происходит непосредственно в строки TMemo.

C#

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

using (Stream fs = new System.IO.FileStream(fullFilePath, 
                                 FileMode.Open,
                                 FileAccess.Read,
                                 FileShare.ReadWrite))
{
  ...
}

либо

using (Stream fs = System.IO.File.Open(fullFilePath, 
                                      FileMode.Open, 
                                      FileAccess.Read, 
                                      FileShare.ReadWrite))
{
}

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

using (StreamReader sr = new StreamReader(fs))
{
    while (!sr.EndOfStream)
    {
        // очередная строка доступна через  sr.ReadLine()
    }
}

В приложенном архиве с примерами (см. следующее сообщение) сделана аналогичная с Delphi программа: периодически по таймеру перечитывается файл и его содержимое отображается в ListBox.

4 (2014-08-24 13:59:10 отредактировано swerg)

Re: Передача данных из Lua-скрипта в другую программу через файл

Общий архив с примерами на разных языках можно скачать здесь
https://quik2dde.ru/static-img/104/ReadFileFromLua.zip