Last active
December 18, 2015 02:28
-
-
Save tkanmae/5710730 to your computer and use it in GitHub Desktop.
Scan records in a Fortran unformatted file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from __future__ import division | |
import itertools | |
import struct | |
def scan_fortran_unformatted(fname, marker_size=4): | |
"""Scan records of a Fortran unformatted file. | |
In unformatted IO, Fortran typically writes the length of a record at the | |
beginning and at the end of the record. They are often called as markers. | |
Most but not all Fortran runtimes use 4 bytes for the markers. | |
Parameters | |
---------- | |
fname: str | |
File name. | |
marker_size: int, optional | |
Marker size in bytes. Default is 4. | |
Returns | |
------- | |
record_struct: list of 4-tuple of ints | |
Record structure. Each tuple contains information about a record block: | |
the record number, the position of the beginning of the record, the | |
number of bytes in the record. | |
""" | |
unpack = struct.unpack | |
if not marker_size in (4, 8): | |
raise ValueError('marker_size must be either 4 or 8.') | |
fmt = 'i' if marker_size == 4 else 'q' | |
with open(fname, 'rb') as fh: | |
record_struct = [] | |
for rec_num in itertools.count(1): | |
buf = fh.read(marker_size) | |
if len(buf) < marker_size: | |
break | |
# Marker at the beginning of the block. | |
marker_beg, = unpack(fmt, buf) | |
# Position of the beginning of the record. | |
pos_beg = fh.tell() | |
# Seek the end of the block. | |
fh.seek(marker_beg, 1) | |
# Marker at the end of the block. | |
marker_end, = unpack(fmt, fh.read(marker_size)) | |
# Both lengths must be the same. | |
assert marker_beg == marker_end | |
record_struct.append((rec_num, pos_beg, marker_beg)) | |
return record_struct |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment