2016-10-24 4 views
0

ファイルを入力として取り込み、出力をstdoutに書き込むFortranコードがあります。読み取り/書き込みサイクルを避けるために、Pythonの内部でコードを実行し、出力をnumpy配列に変換したいと思います。私は次の関数を使用してこれを行うことができます:処理後に外部プログラムから出力を戻す

私は配列をとり、変更してファイルに書き出します。新しいファイルは再びrun_fortran(infile)に渡されます。この手順を回避して、ファイル名を渡す代わりにrun_fortranの出力を使用することはできますか?

ノー成功2つのケースを試みた:

(1)文字列への変換:

arr = run_fortran('input.txt') 
new_arr = str(arr).replace("[","").replace("]","") 
run_fortran(new_arr) 

これは空の配列を返します。 StringIOを使用してファイルタイプのオブジェクトに変換

(2)TypeError: execv() arg 2 must contain only strings理にかなって:

from cStringIO import StringIO 
run_fortran(StringIO(new_arr)) 

これはエラーを返します。

+1

FYI、あなたの代わりに '' Popen' + communicate'の 'check_output'を使用することができます。 –

+1

あなたのfortranプログラムはファイル名を期待しているので、他のものとはうまく動作しません。コマンドライン(またはkeyboard-stdin)からのデータを扱うFortranプログラムを変更すると、ファイルに保存せずにそのまま使用することができます。 – furas

+0

@furas:それは意味がある、ありがとう。私はFortranでそれを行う方法を理解する必要があります! – Mahdi

答えて

0

fortranのread(*,*),またはread*,ステートメントは標準入力から読み込み、正しいフォーマットであれば動作します。必要

do line=1,numlines 
    read(*,*) array(line,:) 
enddo 

ないopenまたはclose文:あなたはformattedデータ、つまり、読める人では何も、ないバイナリファイルを扱っている場合、あなたはおそらくのような読み取りループが必要です。したがって、ファイルに書いていたものが直接渡された場合は、それらの文を削除してunit5または*に変更する必要があります。

ここでは、このようなコミュニケーションを効率的に行う方法がありますが、それがあなたの目的に合っていれば、どんな解決策も良い解決策です。

0

あなたのFortranプログラムは、(それが'./output.e' AFAICSだ)[既存のファイルディスクリプタ(正の整数)、それをstdin=subprocess.PIPEother valid values are」を渡すことによって、一時ファイルなしで行うことができ、通常のファイルからだけではなく、stdinから読み取ることができる場合または]既存のファイルオブジェクト ")。 UNIXの場合、コマンドラインbtwには常に/dev/stdinが、Windowsにはconがあります。

しかし、プログラムは処理の性質上(つまり、連続して実行できず、新しいデータが利用可能になるため)、「セッション」でしか動作できない場合は、繰り返し呼び出す必要があります。

デッドロックを回避するには、異なるスレッドで異なるパイプを処理する必要があることに注意してください。したがって、communicate()を使用するか(プログラムを連続して実行できない)、またはstdout/stderrスレッドを手動で生成するか()、stdinへの書き込みを開始するまで出力読み取りコードを実行する必要があるため、stdinプログラムは、書き込み中に「デバイス上にスペースが残っていない」とチョークする可能性があります)。ここで

が継続的にプログラムを実行するためのサンプルコードです:

p=subprocess.Popen(argv,stdin=subprocess.PIPE,stdout=subprocess.PIPE) 
while True: 
    #the only more elegant way to return a value from a thread is with a Thread subclass, 
    # see http://stackoverflow.com/questions/6893968/how-to-get-the-return-value-from-a-thread-in-python 
    output_container=[] 
    ot=threading.Thread(target=_outputreaderthread,args=(p.stdout,output_container,data)) 
    ot.start() 
    p.stdin.write(data) 
    ot.join() 
    output=output_container[0] 

    data=process_output(output) 
    if no_more_processing_needed(data): break 
p.stdin.close() 
if p.wait()!=0:raise subprocess.CalledProcessError(p.returncode,argv) 

def _outputreaderthread(stream,container,data): 
    #since there's no process termination as an end mark here, 
    # you need to read exactly the right number of bytes to avoid getting blocked. 
    #use whatever technique is appropriate for your data (e.g. readline()'s) 
    output=stream.read(calculate_output_size(data)) 
    container.append(output) 
関連する問題