[gambit-list] Reading binary files
Christian Jaeger
christian at pflanze.mine.nu
Tue Dec 18 11:59:42 EST 2007
Siegfried Gonzi wrote:
> The first 3 numbers in the file are Fortran integer numbers which describe the 3d dimension of the array and the following numbers in the binary file are the content of the array.
>
Depends on whether you're for portability or speed.
A pure-scheme solution (you'll have to adapt if the integers are signed,
or if the matrix doesn't contain integers but floats or so):
(define int-width-in-bytes 4)
(define (u8vector-bigendian-unsigned-number-ref vec pos)
(let lp ((i 0)
(res 0))
(if (< i int-width-in-bytes)
(lp (+ i 1)
(+ res (arithmetic-shift (u8vector-ref vec (+ pos i))
(arithmetic-shift i 3))))
res)))
(define (read-idl-matrix port)
(let* ((dimensions-len (* 3 int-width-in-bytes))
(dimensions (make-u8vector dimensions-len)))
(if (= (read-subu8vector dimensions 0 dimensions-len port) dimensions-len)
(let ((x (u8vector-bigendian-unsigned-number-ref dimensions 0))
(y (u8vector-bigendian-unsigned-number-ref dimensions int-width-in-bytes))
(z (u8vector-bigendian-unsigned-number-ref dimensions (* 2 int-width-in-bytes))))
(let* ((matrix-len (* int-width-in-bytes x y z))
(matrix (make-u8vector matrix-len)))
(if (= (read-subu8vector matrix 0 matrix-len port) matrix-len)
(list x y z matrix)
(error "file too short (2)"))))
(error "file too short (1)"))))
If you're after speed and on a bigendian architecture (or are reading
standard floats or doubles) and don't mind giving up portability, you
could just create a u32vector, s32vector, f64vector or whatever you need
and then fill that in with the unsafe variant of read-subu8vector,
##read-subu8vector. Just be careful you calculate the needed length
correctly.
Christian.
More information about the Gambit-list
mailing list