BDIO in Julia
This package provides an interface to read/write BDIO (Binary Data Input/Output) files in Julia.
Getting started
Here we write a file with two records:
- A record of type
BDIO_BIN_INT64LEthat contains the first 1000 numbers. This record has user info 1. - A record of type
BDIO_BIN_F64LEthat contains a total of 2000 numbers: 1000 random numbers and then the same numbers with opposite sign. This record has user info 2. Note that writing data to a record can be done with more than one call toBDIO_write!.
The MD5 sum of both records is stored in the same BDIO file thanks to the calls to BDIO_write_hash!. These are written in special BDIO records themselves, with user info 7.
julia> using BDIO
julia> BDIO_set_user("alberto")
true
julia> BDIO_set_host("laptop")
true
julia> fb = BDIO_open("foo.bdio", "w", "Test file")
julia> BDIO_start_record!(fb, BDIO_BIN_INT64LE, 1, true)
true
julia> BDIO_write!(fb, collect(1:1000))
true
julia> BDIO_write_hash!(fb)
true
julia> BDIO_start_record!(fb, BDIO_BIN_F64LE, 2, true)
true
julia> vec1 = randn(1000);
julia> vec2 = similar(vec1);
julia> vec2 .= .- vec1;
julia> BDIO_write!(fb, vec1)
true
julia> BDIO_write!(fb, vec2)
true
julia> BDIO_write_hash!(fb)
true
julia> BDIO_close!(fb)
0-element Array{BDIO.Record,1}In total the file has 4 records (2 data records, 2 checksum records). We can see the contents using the lsbdio tool.
$ lsbdio foo.bdio
ID record type size uinf starts with long
0 header v 1 alberto@laptop Wed Jul 1 09:31:24 2020
1 record i64 le 8000 byte 1 1 2 3 4 5 6 7 8 9 10 11 12 13 x
2 record MD5-h 20 byte 7 F41BD4FBFC77E5D5ABDF7300F42C1591 -
3 record f64 le 16000 byte 2 1.378609e-01 -2.838856e-01 x
4 record MD5-h 20 byte 7 1A5636335356BB004E489AB5DAE89B5D -Now let's read the data. We travel the file using BDIO_seek! until we find the records that we are looking for: user info 1 for the integer data and user info 2 for the real data. Again note that reading a single record can be done in chunks with multiple calls to BDIO_read.
julia> using BDIO
julia> fb2 = BDIO_open("foo.bdio", "r")
julia> global isum = 0
0
julia> global fsum = 0.0
0.0
julia> while BDIO_seek!(fb2)
if BDIO_get_uinfo(fb2) == 1
idt = similar(Array{Int64, 1}, 100)
for i = 1:10
BDIO_read(fb2, idt)
global isum += sum(idt)
end
elseif BDIO_get_uinfo(fb2) == 2
fdt = similar(Array{Float64, 1}, 100)
for i = 1:20
BDIO_read(fb2, fdt)
global fsum += sum(fdt)
end
end
end
julia> println("Better be zero: ", fsum)
Better be zero: -1.3322676295501878e-15
julia> println("Better be zero: ", (2*isum - 1000*1001))
Better be zero: 0Setting up global information
BDIO.BDIO_set_user — FunctionBDIO_set_user(us::String)Set user name globally for writing BDIO files.
Arguments
- us: Set
usas the user name when writing BDIO files.
Examples
julia> BDIO_set_user("alberto")BDIO.BDIO_set_host — FunctionBDIO_set_host(us::String)Set host machine globally for writing BDIO files.
Arguments
- us: Set
usas the host when writing BDIO files.
Examples
julia> BDIO_set_host("HLRN")Openning/closing BDIO files
BDIO.BDIO_open — FunctionBDIO_open(fname::String, mode::String, protocol_info::String="")Opens a BDIO file and returns the BDIO handle.
The file can be opened in several modes:
- Write mode ("w"): The file is created and a header written. If the file exists an error is printed.
- Delete mode ("d"): The file is created and a header written. If the file exists it is overwritten.
- Append mode ("a"): The file is created if it does not exist, or opened for appending if the file exists.
- Read mode ("r"): The file is opened for reading.
Arguments
fname: File namemode: The mode in which the file is opened. See above.protocol_info: Only used when the file is created (i.e. "w" or "d" modes) and labels the file.
Examples
julia> fb = BDIO_open("new_file.bdio", "w", "Test file")Returns
A BDIOstream type.
BDIO.BDIO_close! — FunctionBDIO_close!(fb::BDIOstream)Closes the file associated with fb and clears the record database
Arguments
fb: A BDIOstream type. It must be associated with a file.
Examples
```julia-repl julia> fb = BDIOopen("newfile.bdio", "w", "Test file") julia> BDIO_close(fb)
Writing data to BDIO files
BDIO.BDIO_start_record! — FunctionBDIO_start_record!(fb::BDIOstream, ifmt, iuinfo, long::Bool = false)Start a new BDIO record at the end of the file.
Arguments
fb: A BDIOstream type. It must be associated with a file in eitherworamodeifmt: Format. Currently the supported formats areBDIO_BIN_GENERIC: Generic binary dataBDIO_ASC_EXEC: ASCII Executable (i.e.shscript)BDIO_BIN_INT32BE: 32-bit integer in Big Endian formatBDIO_BIN_INT32LE: 32-bit integer in Little Endian formatBDIO_BIN_INT64BE: 64-bit integer in Big Endian formatBDIO_BIN_INT64LE: 64-bit integer in Little Endian formatBDIO_BIN_F32BE: 32-bit float in Big Endian formatBDIO_BIN_F32LE: 32-bit float in Little Endian formatBDIO_BIN_F64BE: 64-bit float in Big Endian formatBDIO_BIN_F64LE: 64-bit float in Little Endian formatBDIO_ASC_GENERIC: ASCII text fileBDIO_ASC_XML: Plain XML data
iuinfo: Integer in the range 0-15. A user specified label to help indentifying the recordlong(optional): If true create a long record. To store more than 1048575 bytes of data ($\approx 1\, {\rm MB}$), a long record is required. Default value offalse.
Examples
julia> fb = BDIO_open("new_file.bdio", "w", "Test file")
julia> BDIO_start_record!(fb, BDIO_BIN_F32, 2)BDIO.BDIO_write! — FunctionBDIO_write!(fb::BDIOstream,data,hash::Bool=true)Write data to BDIO file to the end of the last record.
Arguments
fb: A BDIOstream type. It must be associated with a file in eitherworamode.data: Data to write to file.hash(optional): Bool. If true, data will be checksummed before writtento file. The hash can be stored in a BDIO record by callingBDIO_write_hash(...)
Examples
julia> # Write 1000 normal random numbers to file `randoms.bdio`
julia> fb = BDIO_open("randoms.bdio", "w", "File with random numbers")
julia> BDIO_start_record!(fb, BDIO_BIN_F32, 2)
julia> BDIO_write!(fb, randn(1000))BDIO.BDIO_write_hash! — FunctionBDIO_write_hash!(fb::BDIOstream)Write the MD5 checksum of the actual record as a new record.
Arguments
fb: ABDIOstreamtype. It must be associated with a file in eitherworamode.
Examples
julia> # Write 1000 normal random numbers to file `randoms.bdio` with checksum
julia> fb = BDIO_open("randoms.bdio", "w", "File with random numbers")
julia> BDIO_start_record!(fb, BDIO.BDIO_BIN_F32, 2)
julia> BDIO_write!(fb, randn(1000))
julia> BDIO_write_hash!(fb)Reading data from BDIO files
BDIO.BDIO_read — FunctionBDIO_read(fb::BDIOstream, vdata::Vector, n::Int64 = 0)Read data from BDIO file.
Arguments
fb: A BDIOstream type. It must be associated with a file in eitherworamode.data[:]: AVectorof data to read.n(optional): Integer. If present readnelements ofdata[:]from file
Examples
julia> # Real 1000 floats from the first record of file `randoms.bdio`
julia> fb = BDIO_open("randoms.bdio", "r")
julia> BDIO_seek!(fb)
julia> data = similar({Array, 1}, 1000)
julia> BDIO_read(fb, data)BDIO.BDIO_seek! — FunctionBDIO_seek!(fb::BDIOstream, icnt::Int = 1)Move the read position backward/forward icnt records
Arguments
fb: A BDIOstream type. It must be associated with a file.icnt(optional): number of records to move forward (ificnt>0) or backwards (icnt<0). Ificnt=0move to the first record. The default value is+1.
Examples
julia> # count number of records in a file.
julia> fb = BDIO_open("randoms.bdio", "r")
julia> count = 0
julia> while BDIO_seek!(fb)
julia> count += 1
julia> endObtaining information about BDIO records
BDIO.BDIO_get_uinfo — FunctionBDIO_get_uinfo(fb::BDIOstream)Returns the user provided info of each record
Arguments
fb: ABDIOstream type. It must be associated with a file.
Examples
julia> # Write length of all records
julia> fb = BDIO_open("randoms.bdio", "r")
julia> while BDIO_seek!(fb)
julia> count += 1
julia> println("Record: ", count, " user info: ", BDIO_get_uinfo(fb))
julia> endBDIO.BDIO_get_len — FunctionBDIO_get_len(fb::BDIOstream)Returns the len (in bytes) of the current record
Arguments
fb: ABDIOstreamtype. It must be associated with a file.
Examples
julia> # Write length of all records
julia> fb = BDIO_open("randoms.bdio", "r")
julia> while BDIO_seek!(fb)
julia> count += 1
julia> println("Record: ", count, " length: ", BDIO_get_len(fb), " bytes")
julia> endBDIO.BDIO_get_fmt — FunctionBDIO_get_fmt(fb::BDIOstream)Returns the format of the current record
Arguments
fb: ABDIOstreamtype. It must be associated with a file.
Examples
julia> # Print all BDIO_BIN_GENERIC records
julia> fb = BDIO_open("randoms.bdio", "r")
julia> while BDIO_seek!(fb)
julia> count += 1
julia> if (BDIO_get_fmt(fb) == BDIO_BIN_GENERIC)
julia> println("Record: ", count, " is BIN_GENERIC")
julia> end
julia> end