2016-09-09 12 views
1

とFORTRANバイナリ(ストリーミングアクセス)を読み取る次のFortranコード:np.fromfile又はオープン&構造体

INTEGER*2 :: i, Array_A(32) 
Array_A(:) = (/ (i, i=0, 31) /) 

OPEN (unit=11, file = 'binary2.dat', form='unformatted', access='stream') 
    Do i=1,32 
     WRITE(11) Array_A(i) 
    End Do 
CLOSE (11) 

は整数16ビット31は0から番号付きバイナリ出力を生成し、ストリーミング。各レコードは2バイトを占めているので、バイト1,3,5,7などで書き込まれます。 access = 'stream'は、各レコードのFortranの標準ヘッダーを抑制します(ファイルをできるだけ小さくするために必要です)。ヘックス・エディタでそれを見て

は、私が取得:

完全に罰金です
00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 
08 00 09 00 0A 00 0B 00 0C 00 0D 00 0E 00 0F 00 
10 00 11 00 12 00 13 00 14 00 15 00 16 00 17 00 
18 00 19 00 1A 00 1B 00 1C 00 1D 00 1E 00 1F 00 

(小数点以下は、私の例では低すぎるため、2番目のバイトは、決して使用されているという事実にもかかわらず)。

これらのバイナリファイルをPython 2.7にインポートする必要がありますが、できません。私は多くの異なるルーチンを試しましたが、私はいつもそうしています。

1.試み: "np.fromfile"

with open("binary2.dat", 'r') as f: 
    content = np.fromfile(f, dtype=np.int16) 

戻り

[ 0  1  2  3  4  5  6  7  8  9 10 11 
    12 13 14 15 16 17 18 19 20 21 22 23 
    24 25  0  0 26104 1242  0  0] 

2.試み: "構造体"

import struct 
with open("binary2.dat", 'r') as f: 
    content = f.readlines() 
    struct.unpack('h' * 32, content) 

を実現します

print content 
['\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\t\x00\n', '\x00\x0b\x00\x0c\x00\r\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00'] 

は(区切り文字、TおよびFortranの "ストリーミング" のアクセスが何をするかによるがあってはならないn個の点に注意してください)

struct.error: unpack requires a string argument of length 64 

ので

3.試み: "FortranFile" エラーで

f = FortranFile("D:/Fortran/Sandbox/binary2.dat", 'r') 
print(f.read_ints(dtype=np.int16)) 

TypeError: only length-1 arrays can be converted to Python scalars 

(ファイルの途中でデリミタがどのように検出されたかを覚えていますが、改行なしの短いファイルの場合はクラッシュします。 0から8までの小数))

いくつかの追加の考え:

Pythonはバイナリファイルの読み取り部分とのトラブルを持っているようです。 np.fromfileの場合はHex 19(dec:25)と表示されますが、Hex 1A(dec:26)でクラッシュします。それは文字と混同されているようですが、0A、0B ...うまく動作します。

試行2では、content -resultが奇妙です。小数点以下0~8は正常に動作しますが、次にこの奇妙な\t\x00\nものがあります。それではhex 09とは何ですか?

私はロジックを見つけるのに何時間も費やしてきましたが、私は立ち往生しており、本当に助けが必要です。何か案は?

答えて

3

問題はオープンファイルモードです。デフォルトは 'text'です。このモードをバイナリに変更してください:

with open("binary2.dat", 'rb') as f: 
    content = np.fromfile(f, dtype=np.int16) 

すべての数字が正常に読み込まれます。詳細については、PythonのダイブBinary Filesを参照してください。

+0

Omg、それは1文字ですか?どのように私はこれを見ることができないでしょう... とにかく、とにかく、ありがとう - 私の日を救ってくれてありがとう! – offeltoffel