我在SWI Prolog和Windows 7上運行我的代碼。在我的代碼中,我使用'win_exec()'調用另一個應用程序(我嘗試使用方法'shell() ',但它不起作用。),最後在文本文件中輸出它的輸出。但有時它會運行30分鐘。現在我的序言代碼使用這個輸出文本文件來進一步解析並處理它。 這是我用來調用其他應用程序,然後使用它的輸出文件的代碼:文件異常處理和等待SWI中的進程Prolog
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)
因此,作爲一種解決方法,我嘗試捕獲錯誤,通過與'exists_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中的文件流。我嘗試過使用它,但它會給出錯誤。
任何幫助或指導,非常感謝。
謝謝您的建議。它們都很好,但是我最初不想使用sleep/1,因爲它會弄亂我的統計/ 2,因爲我想計算整個過程所花費的時間。另外,其他應用程序有時以秒爲單位輸出,而在其他時間甚至需要幾小時。所以我擔心我的代碼是否會崩潰。我理解一些技術,比如只是輪詢一下,或者中斷不能在這裏工作。 – shujin
我已經添加了方法(3),我希望它更適合您的場景:使用'process_wait/2'來等待被調用的進程結束,然後讀取文件。您可能必須稍微改變流程被調用的方式才能執行此操作。還要注意,你可以使用例如'sleep(0。1)',顯着降低CPU負載並保持更好的性能。 – mat
但我正在考慮像1)我的代碼調用另一個win_shell/3或win_exec/2(並行任務),它運行一些腳本,檢查輸出文件的存在並將狀態返回到代碼。或者,2)我不是直接調用win_exec來調用其他應用程序,而是使用win_exec來調用'cmd.exe/K external_app.bat',並讓cmd告訴我輸出文件存在的狀態。我不知道有這樣的CMD開關可以完成這項工作。由於cpu循環過多,希望代碼不會崩潰,因此open_aux_wait應該執行尾遞歸,因此不應該發生堆棧溢出。 – shujin