Thanks a lot Fransesc and Neil, yours messages really help me.
I'll look at these solutions attentively.
Here is what I write recently, but I begin to understand it's effectively not portable...
def fread(fileObject,*arrayAttributs):
""" Reading in a binary (=unformatted) Fortran file
Let's call 'record' the list of arrays written with one write in the Fortran file.
Call one fread per write.
Parameter :
* fileObject, eg: fileObject = open("data.bin",'rb')
* arrayAttributs = ( (shape1,dtype1,readorskip1), (shape2,dtype2,readorskip2) ...)
* shape: eg: (100,200)
* dtype: eg: '<f4' (little endian, simple precision), '>f8' (big endian, double precision)
* readorskip = [0|1]
* 1: the array is read and return
* 0: the size of the array is skipped to read the array after, the array isn't returned
Exemples (with write ux,uy,p in the Fortran code)
* f = open("uxuyp.bin",'rb')
nx,ny = 100,200
p = readFortran( f, ((nx,ny),'<f8',0), ((nx,ny),'<f8',0), ((nx,ny),'<f8',1) )
f.close
"""
import numpy,os,utils
# compute the recordSize to be read
recordBytes = 8
for (shape,dtype,read) in arrayAttributs:
dtype = numpy.dtype(dtype)
# number of elements to be read in this array
count = 1
for size in shape:
count *= size
# size of the record
recordBytes += count*dtype.itemsize
# the fileSize
fileSize = os.stat(fileObject.name)[6]
# compare recordSize and fileSize
if recordBytes > fileSize:
import logging
logging.error('To much data to be read in %r',fileObject.name)
logging.error('File Size: %r',fileSize)
logging.error('To be read: %r',recordBytes)
NoneList = []
for (shape,dtype,read) in arrayAttributs:
if read: NoneList.append(None)
return NoneList
# skip the four bytes in the beginning of the record
fileObject.seek(4,1)
# read the arrays in record
arrays = []
for (shape,dtype,read) in arrayAttributs:
# number of elements to be read in this array
count=1
for size in shape:
count *= size
if read:
array = numpy.fromfile(fileObject, count=count, dtype=dtype).reshape(shape, order='F')
arrays.append(array)
else:
dtype = numpy.dtype(dtype)
arrayBytes = count*dtype.itemsize
fileObject.seek(arrayBytes,1)
# skip the four bytes at the end of the record
fileObject.seek(4,1)