2015-11-10 57 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 ......'在第一次尝试中运行良好!非常感谢! –