Reading Data
Base.read — Functionread(f::FortranFile [, spec [, spec [, ...]]])
read(f::FortranFile, rec=N, [, spec [, spec [, ...]]])Read data from a FortranFile. Like the READ statement in Fortran, this reads a complete record, regardless of how man specs are given. Each spec can be:
- a
DataTypefor scalar values; e.g.Int32,Float64,FString{10} - a tuple of
DataTypeand one or more integers, for reading arrays of the given size; e.g.(Int32,4,2)reads anArray{Int32}of size (4,2) - a tuple of
DataTypeand a tuple of integers, as an alternative way of reading arrays; e.g.(Int32,(4,2))does the same as the previous one - an array, for reading into pre-allocated arrays;
DataTypeand size of the array are implied through its Julia type.
For direct-access files, the number of the record to be read must be specified with the rec keyword (N=1 for the first record).
Return value:
- if no
specis given:nothing(the record is skipped over) - if one
specis given: the scalar or array requested - if more
specs are given: a tuple of the scalars and arrays requested, in order
FortranFiles.@fread — Macro@fread f [ rec=N ] [ spec ... ]Macro interface for reading data from the FortranFile f. A single @fread call will process a single data record from the file. Each spec can be:
- a
var::Tdeclaration, which will read data of the typeTfrom the file, and assign it to the variablevar.Tcan be one of the usual Fortran scalar datatypes. - a
var::(T,dims...)declaration, whereTis a scalar datatype anddims...is a series of integers. This reads an array of the specified datatype and dimensions, and assigns it to the variablevar. var::Array{T}(undef,dims...)as an explicit form for reading arrays- a variable name, which must refer to a pre-allocated array.
Note that a spec can refer to variables assigned by previous specs. The rec keyword must be given iff f refers to a direct-access file, and specifies which record to read.
Example:
@fread f n::Int32 x::(Float64,n)This reads a single Int32, assigns it to n, and then reads a Float64 array with n elements and assigns it to x. Such a record can not be processed by the function-based read interface. The equivalent call would be
n, x = read(f, Int32, (Float64,n))but this can't work because n is only assigned after the read statement is processed. The macro interface is provided to cover such cases.
Examples
The following examples show how to write Julia code that corresponds to certain Fortran READ statements. The Julia code assumes that f refers to an opened FortranFile in sequential access mode, while the Fortran code assumes that lun refers to a logical unit number for a connected file.
For direct access mode, each read call additionally needs to specify the number of the record to read, by using the rec keyword argument. E.g. to read the first record, use read(f, rec=1, ...).
The @fread macro can be used if the size of data to be read from a record depends on earlier data from the same record. See example below.
Reading a single scalar
x = read(f, Float64)corresponds to
real(kind=real64)::x
read(lun) xReading a 1D array
vector = read(f, (Float64,10)) # read into a new array
vector = zeros(10); read(f, vector) # read into pre-existing arraycorresponds to (Modern Fortran style)
real(kind=real64),dimension(10)::vector
read(lun) vectorand to (Fortran77 style)
integer::i
real(kind=real64),dimension(10)::vector
read(lun) (vector(i), i=1,10)Reading a 2D array
matrix = read(f, (Float64,10,10)) # read into a new array
matrix = read(f, (Float64,(10,10))) # alternative syntax
matrix = zeros(10,10); read(f, matrix) # read into existing array
corresponds to
real(kind=real64),dimension(10,10)::matrix
read(lun) matrixReading a character string
fstr = read(f, FString{20})corresponds to
character(len=20)::fstr
read(lun) fstrReading a record with multiple data
i, strings, zmatrix = read(f, Int32, (Fstring{20},10), (ComplexF64,10,10))corresponds to
integer(kind=int32)::i
character(len=20),dimension(10)::strings
complex(kind=real64),dimension(10,10)::zmatrix
read(lun) i,strings,matrixReading a record where the size is not known ahead
@fread f n::Int32 vector::(Float64,n)corresponds to
integer(kind=int32)::n,i
read(kind=real64),dimension(*)::vector ! assume already allocated
read(lun) n,(vector(i),i=1,n)Skipping over a record
read(f)corresponds to
read(lun)