2015-11-10 87 views
1

我不得不與名稱的一部分打開文件稱爲

open(unit,file='x',status='old',action='read',iostat=io_error) 

的問題是,我只知道,因爲最後部分的文件的名稱的一部分,是一個數字,其改變在每次執行程序的時間和我不知道數字生成的系統(extern庫)。

有沒有辦法只打開一部分名稱的文件?

+0

不在純粹的Fortran中。您必須使用其他方法來搜索目錄中的文件。可能是使用shell的東西。你使用哪種操作系統? –

+0

Ubuntu。你的意思是像SYSTEM這樣的東西嗎? –

+0

是,SYSTEM或EXECUTE_COMMAND_LINE這是標準聲明。創建一些bash腳本,它將確定正確的名稱並將其保存在某個地方。然後在Fortran中讀取保存的文件名。 –

回答

1

不幸的是,在打開它之前,您需要知道文件名。 Fortran在這方面缺乏的一件事是檢查文件系統的能力。您的選擇歸結爲

  • EXECUTE_COMMAND_LINESYSTEM調用外部程序,或
  • 使用iso_c_binding功能調用C標準庫函數。

我發現第二個選項有點麻煩,因爲你需要做的調用涉及到很多typdef'd類型,結構和C指針。這當然是可行的,但如果您不熟悉Fortran/C interop,這將不是最直接的。

調用execute_command_linesystem從某種意義上說'更容易',因爲如果您可以編寫shell命令來查找文件名,那麼您已經有了一個解決方案。

作爲一個例子,我有一個庫讀取HDF5數據與N個文件,其中N是基於模型時間步長,可能是不規則的。而不是把負擔放在用戶列舉文件上,我和你處於類似的位置。我會解決你問題的版本的方法是這樣的:

character(len=*), parameter :: temporary_file = '/tmp/something_unique' 
character(len=*) :: filename_fragment, filename 
integer :: u 

call execute_command_line('find . -name '//trim(filename_fragment)// & 
          "* -printf '%f\n' > "//trim(temporary_file) 
open(newunit=u, file=temporary_file, action="read") 
read(u, '(A)') filename 
close(u) 

如果filename_fragment是你知道名字的一部分,這是比find呼叫與輸出重定向而已。例如。如果filename_fragment是「datasetABC_」這將運行

find . -name 'datasetABC_*' -printf '%f\n' > /tmp/something_unique 

和文件/tmp/something_unique將包含每個符合您的搜索行一個文件名。您可能需要將參數調整爲find才能適用於您的特定情況,但這是您如何繼續操作的一般想法。一旦你有這個工作,你只需打開/tmp/something_unique並從文件中讀取完整的文件名,現在你知道全名來打開它們。

*注意:上述解決方案假定您的find將只返回一個文件名。如果它有多個匹配項,則需要在Fortran中優化搜索或處理該案例以從臨時文件中的文件名中獲取正確的文件。

+0

非常感謝您的回答,我會在明天看到它。由於我已經在使用iso_c_binding(外部庫是C/C++),可能它並不那麼困難。我們明天再見。 –

+0

'execute_command_line('find ......'在第一次嘗試中運行良好!非常感謝! –