function mark_Fail (zap, mark) - моя функция записи в файл FileWrite = io.open('D:\\QLUA\\fails\\mark.txt', zap) FileWrite:write(mark) FileWrite:close() end а другой скрипт читает этот файл. Все работает нормально, но периодически первый скрипт выходит на ошибку "attempt to use a closed file" на строке FileWrite:close(). Ошибка выходит редко, 2-3 раза в день, при этом запись в файл примерно каждые 6-8 секунд, а просмотр другим скриптом каждые 60 секунд) Я своим скудным умишком полагаю, что происходит наложение запросов двух скриптов на один файл и конфликт. Вопросы: 1) как сделать "бесшовную" работу нескольких скриптов с одним файлом? Не запись одновременно, а один скрипт пишет - несколько читают и не мешают основному писать. 2) на крайняк, как сделать, чтоб не останавливало скрипт по такой ошибке? Готов просто пропускать запись, если вдруг прошло "наложение" в этот момент Заранее благодарю отозвавшихся на вопрос.
Дмитрий написал: function mark_Fail (zap, mark) - моя функция записи в файл FileWrite = io.open('D:\\QLUA\\fails\\mark.txt', zap) FileWrite:write(mark) FileWrite:close()end
попробуйте так:
Код
function mark_Fail (zap, mark) - моя функция записи в файл
FileWrite = io.open('D:\\QLUA\\fails\\mark.txt', zap)
FileWrite:write(mark)
if Filewrite then FileWrite:close() end
end
Спасибо. А вы не могли бы в 2-х словах пояснить как работает условие без значения, ну т.е. я понимаю когда, например " if Filewrite == nil then ... ", а что значит переменная без сравнения в конструкции " if Filewrite then ..." ?
И что-то такая конструкция работает не правильно, теперь у меня файл до остановки скрипта пустой. Наверное, скрипт держит его открытым и не фиксирует запись.
Дмитрий написал: Спасибо. А вы не могли бы в 2-х словах пояснить как работает условие без значения, ну т.е. я понимаю когда, например " if Filewrite == nil then ... ", а что значит переменная без сравнения в конструкции " if Filewrite then ..." ?
оператор if исполняется если следующее выражение true. если File что-то присвоено, то это true.
Дмитрий написал: И что-то такая конструкция работает не правильно, теперь у меня файл до остановки скрипта пустой. Наверное, скрипт держит его открытым и не фиксирует запись.
Если хотите передавать данные через файл, то надо делать один из следующих алгоритмов: либо контролировать момент изменения файла, либо уничтожать его после чтения либо делать уникальное имя либо писать метку в строку и искать эту метку.
Дмитрий написал: "либо писать метку в строку и искать эту метку" - а это как работает?
скрипт открывает файл на дозапись и пишет лог файл. каждая запись содержит метку времени . другой скрипт открывает файл на чтение и читает этот файл по строкам. Время в метке сравнивает с текущим временем и читает строки, время которых больше.
В моей ситуации, я так понимаю, это не поможет. У меня 2 скрипта иногда открывают один и тот же файл (мне надо иметь общий файл, а одновременное открытие - совпадение, которое надо как-то нейтрально обходить), а потом кто-то его первый закрывает, а второй при попытке закрыть еще раз выдает ошибку. Я так это вижу исходя из того, что именно на FileWrite:close() в первом скрипте происходит ошибка (во втором скрипте открывает на чтение и отрабатывает быстрее - там никогда ошибку не выдает - я там вообще только первую строку читаю, больше не надо). Отсюда вопрос: а как-то статус, что файл стал "close" можно получить запросом? пытался выводить значение переменной "FileWrite" через "tostring", чтоб по нему как-то зацепиться, но выдает какой-то буквенно-цифровой код, описание структуры которого в инете найти не смог.
Дмитрий написал: В моей ситуации, я так понимаю, это не поможет. У меня 2 скрипта иногда открывают один и тот же файл (мне надо иметь общий файл, а одновременное открытие - совпадение, которое надо как-то нейтрально обходить), а потом кто-то его первый закрывает, а второй при попытке закрыть еще раз выдает ошибку. Я так это вижу исходя из того, что именно на FileWrite:close() в первом скрипте происходит ошибка (во втором скрипте открывает на чтение и отрабатывает быстрее - там никогда ошибку не выдает - я там вообще только первую строку читаю, больше не надо). Отсюда вопрос: а как-то статус, что файл стал "close" можно получить запросом? пытался выводить значение переменной "FileWrite" через "tostring", чтоб по нему как-то зацепиться, но выдает какой-то буквенно-цифровой код, описание структуры которого в инете найти не смог.
У меня один лог файл. В него пишут разные потоки. Так как я могу создавать любое число потоков и Lua машин, то мне нет надобности создавать еще какие-то скрипты. Но мой вариант работы эквивалентен вашему варианту с двумя скриптами. У меня проблемы запись в этот файл. Попробуйте открывать файлы один раз с дозаписью и завершать запись принудительной записью в файл. типа так: Log:write(os.date()..","..tostring(s)..",num="..tostring(num)..","..tostring(count).."\n"); Log:flush();
Дмитрий написал: function mark_Fail (zap, mark) - моя функция записи в файл FileWrite = io.open('D:\\QLUA\\fails\\mark.txt', zap) FileWrite:write(mark) FileWrite:close() end а другой скрипт читает этот файл.
Вы бы написали ещё как читаете. У меня записываются данные в файл одним скриптом и читаются другим в 10 раз чаще и не было подобных проблем. Не знаю как вы читаете, могу предположить, что открываете и закрываете файл при каждом чтении. В этом нет необходимости, открывайте файл на чтение в начале работы читающего скрипта и закрывайте файл в конце работы непосредственно перед остановкой. Попробуйте.
nikolz написал: У меня один лог файл. В него пишут разные потоки. Так как я могу создавать любое число потоков и Lua машин, то мне нет надобности создавать еще какие-то скрипты. Но мой вариант работы эквивалентен вашему варианту с двумя скриптами.У меня проблемы запись в этот файл. Попробуйте открывать файлы один раз с дозаписью и завершать запись принудительной записью в файл.типа так: Log:write(os.date()..","..tostring(s)..",num="..tostring(num)..","..tostring(count).."\n"); Log:flush();
Вот это, наверное, то, что нужно, только я не понял всю конструкцию - как открыть один раз и потом дописывать? т.е. просто у вас один раз в начале открыт Log = io.open('...', 'a'), а потом уже без открытия просто по ходу вставляете Log:write(os.date()..' и так дает дописывать? p.s. я кажется свою проблему понял, у меня не второй скрипт конфликтил с первым, у меня в первом колбеки могли при стечении обстоятельств писать "логи" одновременно с main(), а так как я постоянно "io.open" и "close' при каждой записи - получалась коллизия, а если буду держать файл открытым, то будут писать оба без ругани, получается. Так?
nikolz написал: У меня один лог файл. В него пишут разные потоки. Так как я могу создавать любое число потоков и Lua машин, то мне нет надобности создавать еще какие-то скрипты. Но мой вариант работы эквивалентен вашему варианту с двумя скриптами.У меня проблемы запись в этот файл. Попробуйте открывать файлы один раз с дозаписью и завершать запись принудительной записью в файл.типа так: Log:write(os.date()..","..tostring(s)..",num="..tostring(num)..","..tostring(count).."\n"); Log:flush();
Вот это, наверное, то, что нужно, только я не понял всю конструкцию - как открыть один раз и потом дописывать? т.е. просто у вас один раз в начале открыт Log = io.open('...', 'a'), а потом уже без открытия просто по ходу вставляете Log:write(os.date()..' и так дает дописывать? p.s. я кажется свою проблему понял, у меня не второй скрипт конфликтил с первым, у меня в первом колбеки могли при стечении обстоятельств писать "логи" одновременно с main(), а так как я постоянно "io.open" и "close' при каждой записи - получалась коллизия, а если буду держать файл открытым, то будут писать оба без ругани, получается. Так?
Если надо не только передавать но и обмениваться, то проще открыть каждому скрипту свой файл для передачи данных другим с ключом "w". Файлы других скриптов открываете с ключом "r"
Hазобрался, настроил, вроде работает как надо. спасибо. Последний вопрос для закрепления материала ))) а вот эта запись " Log:flush() " - что означает в вашем примере записи в Log ?
Дмитрий написал: Hазобрался, настроил, вроде работает как надо. спасибо. Последний вопрос для закрепления материала ))) а вот эта запись " Log:flush() " - что означает в вашем примере записи в Log ?
Log - это имя файла моего - я вам дал пример строки из своего скрипта. flush() - записать данных в файл, иначе они запишутся в память, а в файл лишь после того ,как накопятся в памяти. .