Обработка исключений файлов и ожидание процесса в SWI Prolog
Я выполняю свой код на SWI Prolog и Windows 7. В моем коде я вызываю другое приложение, используя 'win_exec()' (я пытался использовать метод 'shell()', но он не работает.), И на end производит вывод в текстовом файле. Однако иногда это работает в течение 30 минут. Теперь мой пролог-код использует этот выходной текстовый файл для дальнейшего его анализа и обработки. Это код, который я использую для вызова другого приложения, а затем использовать его выходной файл:
main(Value,X) :- win_exec('C:\\myfolder\\external_app.bat C:\\myfolder\\outputfile.txt', normal),
open('C:\\myfolder\\outputfile.txt', read, Mf),
read_file(Mf, X), % PROCEDURE TO READ FILE CONTENTS
close(Mf),
statistics(cputime, Value). % CALCULATE HOW LONG IT TOOK
Однако, поскольку файл не был выведен этим другим приложением, он выдает ошибку:
ERROR: open/4: source_sink `C:\myfolder\outputfile.txt' does not exist (No such file or directory)
Поэтому, в качестве обходного пути, я пытаюсь отловить ошибку, обработать ее, сравнивая с "creation_error", а затем рекурсивно вызвать процедуру open, пока она не завершится успешно, то есть другое приложение не завершит свою обработку и не будет создан выходной файл. Это мой обходной код для этого:
main(Value,X) :- win_exec('C:\\myfolder\\external_app.bat C:\\myfolder\\outputfile.txt', normal),
open_output(X), % PROCEDURE FOR FILE EXCEPTION HANDLING
statistics(cputime,Value).
open_output(X) :- catch((open('C:\\myfolder\\outputfile.txt', read, Mf), read_file(Mf,X), close(Mf)),
error(Err,Context),
open_output_aux(Err,X)). % AUX PROCEDURE TO RECOVER
% Write some code here
% open_output_aux code matches the error code with 'existence_error';
% if true, calls open_aux_wait procedure; else throw the error.
open_aux_wait(Z):- catch((open('C:\\myfolder\\outputfile.txt', read, Mf), read_file(Mf,Z), close(Mf)),
error(Err,Context),
open_aux_wait(Z)).
Однако это кажется очень неэффективным способом сделать это. Я хотел знать, есть ли лучший способ сделать это, например, в Java, вы могли бы просто вызвать wait() при обработке исключения файла. В документации есть метод wait_for_input\3, но он говорит, что wait_for_input() нельзя использовать для потоков файлов в Windows. Я пытался использовать его, но он дает ошибку.
Любая помощь или рекомендации с благодарностью.
1 ответ
У вас есть несколько вариантов решения этой проблемы:
Вы можете полностью пересмотреть способ взаимодействия этих процессов. Например, SWI-Prolog поставляется с очень мощными библиотеками HTTP, и вы можете настроить связь между двумя процессами для работы по HTTP, используя архитектуру клиент / сервер. В этом случае вы избегаете ожидания занятости, которое в настоящее время использует много циклов ЦП без необходимости.
Гораздо более тривиальное решение - просто вставить вызов встроенного
sleep/1
предикат, чтобы перевести процесс в спящий режим, прежде чем пытаться снова открыть файл. Использовать напримерsleep(1)
уложить процесс на 1 секунду.Использовать например
process_wait/2
подождать, пока вызванный процесс завершит работу и сгенерирует файл.
Из того, что вы описываете, похоже, что (2) будет делать, (3) немного более элегантно, и (1) может быть полезно знать в целом, для более сложных случаев.