[Numpy-discussion] example reading binary Fortran file

David Froger david.froger.info at gmail.com
Tue Feb 3 13:30:46 EST 2009


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)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20090203/6c355486/attachment.html>


More information about the NumPy-Discussion mailing list