Skip to main content

H5File

Struct H5File 

Source
pub struct H5File { /* private fields */ }
Expand description

An HDF5 file opened for reading or writing.

Datasets created from this file hold a shared reference to the underlying I/O handle, so the file does not need to outlive its datasets (they share ownership via reference counting).

Implementations§

Source§

impl H5File

Source

pub fn create<P: AsRef<Path>>(path: P) -> Result<Self>

Create a new HDF5 file at path. Truncates if the file already exists.

Source

pub fn open<P: AsRef<Path>>(path: P) -> Result<Self>

Open an existing HDF5 file for reading.

Source

pub fn open_rw<P: AsRef<Path>>(path: P) -> Result<Self>

Open an existing HDF5 file for appending new datasets.

Existing datasets are preserved. New datasets can be added and will be written after the current end of file. Existing chunked datasets can be extended with write_chunk and extend_dataset.

use rust_hdf5::H5File;
let file = H5File::open_rw("existing.h5").unwrap();
let ds = file.new_dataset::<f64>().shape(&[100]).create("new_data").unwrap();
ds.write_raw(&vec![0.0f64; 100]).unwrap();
file.close().unwrap();
Source

pub fn options() -> H5FileOptions

Start building open options for an HDF5 file.

Use this to control file-locking behavior explicitly:

use rust_hdf5::{H5File, FileLocking};
// Open with locking disabled (e.g. on NFS without lock support).
let file = H5File::options()
    .locking(FileLocking::Disabled)
    .open_rw("existing.h5")
    .unwrap();
Source

pub fn set_libver_latest(&self, latest: bool) -> Result<()>

Opt in to the latest file format for datasets created after this call — the equivalent of libhdf5’s H5Pset_libver_bounds(low = H5F_LIBVER_V200).

With latest set, filtered chunked datasets get a version-5 data layout message, whose chunk indexes store on-disk chunk sizes in fixed-width (sizeof_size, i.e. 8-byte) fields instead of fields sized from the uncompressed chunk size. That removes the overflow risk when a filter expands a chunk, but the file is only readable by libhdf5 ≥ 2.0 (h5py bundling hdf5 1.14 rejects it with “bad version number”).

It also sets the file’s library-version low bound, and so its superblock version: version 3, where a file this crate writes without it is version 2 (or 3 anyway, once it holds a chunked dataset).

Off by default; the data layout of unfiltered and contiguous datasets is unaffected. Independent of this setting, a chunk larger than 4 GiB forces version 5 because version 4 cannot represent its size field, matching libhdf5.

false is not “back to the default”: it is LibverBound::Earliest, the opposite end of the same table, where the data layout message is version 3 and chunked datasets created after the call go on the version-1 B-tree. A file that has never been told a bound is the one at the crate default.

Errors in read mode.

Source

pub fn set_libver_bound(&self, libver: LibverBound) -> Result<()>

Set the file’s low libver bound — H5Pset_libver_bounds’s low argument, the oldest libhdf5 release the file must stay readable by.

Objects created after this call encode their messages at the versions that bound calls for: a compound, enum or array datatype message moves to version 3 at LibverBound::V18 and version 4 at LibverBound::V112, the way H5T_set_version upgrades a datatype, while an integer or string message stays at version 1 in every file. LibverBound::V200 additionally selects the version-5 data layout for filtered chunked datasets, as Self::set_libver_latest does.

The bound also picks the chunk index, through the data layout message version H5O_layout_ver_bounds gives it: below LibverBound::V110 that version is 3, which has no index-type field, so a chunked dataset created after this call is indexed by the version-1 B-tree rather than by the v1.10 index its shape would otherwise select. Datasets already created keep the index they were made with, exactly as libhdf5 keeps what a dataset’s creation property list settled.

Naming a bound is not the same as leaving it unset: a file created through H5File::create names none and uses the v1.10 indexes.

Errors in read mode.

Source

pub fn set_track_order(&self, track: bool) -> Result<()>

Record creation order for the links and the attributes of every object created after this call — the equivalent of h5py’s h5py.get_config().track_order = True, i.e. H5Pset_link_creation_order and H5Pset_attr_creation_order set to H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED on the creation property lists those objects are made with.

Creation-order tracking belongs to the object, so groups and datasets made before this call keep the policy they were made under — the same split h5py has between its global config and each object’s property list. The root group is created with the file; configure it with H5FileOptions::track_order, h5py’s File(..., track_order=True).

Off by default. Errors in read mode.

Source

pub fn set_track_times(&self, track: bool) -> Result<()>

Record the times of every object created after this call — H5Pset_obj_track_times on the creation property lists those objects are made with, h5py’s track_times= argument to create_dataset and create_group.

Off by default; see H5FileOptions::track_times for why that is h5py’s answer and not libhdf5’s. Like creation-order tracking it belongs to the object, so objects made before this call keep the policy they were made under, and the root group takes its own from H5FileOptions::track_times.

Errors in read mode.

Source

pub fn root_group(&self) -> H5Group

Return a handle to the root group.

The root group can be used to create datasets and sub-groups.

Source

pub fn create_group(&self, name: &str) -> Result<H5Group>

Create a group in the root of the file.

use rust_hdf5::H5File;
let file = H5File::create("groups.h5").unwrap();
let grp = file.create_group("detector").unwrap();

Create a soft link in the root of the file.

See H5Group::create_soft_link.

use rust_hdf5::H5File;
let file = H5File::create("soft.h5").unwrap();
file.new_dataset::<i32>().shape([8]).create("orig").unwrap();
file.create_soft_link("alias", "/orig").unwrap();

Create an external link in the root of the file.

See H5Group::create_external_link.

use rust_hdf5::H5File;
let file = H5File::create("master.h5").unwrap();
file.create_external_link("ext", "payload.h5", "/data").unwrap();
Source

pub fn commit_datatype( &self, name: &str, datatype: DatatypeMessage, ) -> Result<()>

Commit a datatype in the root of the file.

See H5Group::commit_datatype.

use rust_hdf5::H5File;
use rust_hdf5::format::messages::datatype::DatatypeMessage;
let file = H5File::create("committed.h5").unwrap();
file.commit_datatype("temperature", DatatypeMessage::f64_type()).unwrap();
Source

pub fn new_dataset<T: H5Type>(&self) -> DatasetBuilder<T>

Start building a new dataset with the given element type.

This returns a fluent builder. Call .shape(...) to set dimensions and .create("name") to finalize.

let file = H5File::create("build.h5").unwrap();
let ds = file.new_dataset::<f64>().shape(&[3, 4]).create("matrix").unwrap();
Source

pub fn set_attr_string(&self, name: &str, value: &str) -> Result<()>

Add a string attribute to the file (root group).

The value is stored as a variable-length UTF-8 string (read back as a Python str by h5py), not a fixed-length string.

Source

pub fn set_attr_numeric<T: H5Type>(&self, name: &str, value: &T) -> Result<()>

Add a numeric attribute to the file (root group).

Source

pub fn set_attr_typed( &self, name: &str, datatype: DatatypeMessage, value: Vec<u8>, ) -> Result<()>

Add a scalar attribute to the file (root group) whose datatype and raw value the caller supplies.

The escape hatch for a type this crate has no Rust mapping for — a fixed-length string of a size the value alone does not imply, say, which is what H5Tcopy(H5T_C_S1) plus H5Tset_size produces. DatasetBuilder::datatype is the same hatch for a dataset; every typed setter here builds one of these underneath.

value is the raw element image and must be exactly as long as the datatype’s element size.

let file = H5File::create("notes.h5").unwrap();
let mut text = vec![b'x'; 256];
text[255] = 0;
file.set_attr_typed(
    "note",
    DatatypeMessage::FixedString { size: 256, padding: 0, charset: 0 },
    text,
)
.unwrap();
Source

pub fn set_attr_array_numeric<T: H5Type>( &self, name: &str, values: &[T], ) -> Result<()>

Add a numeric (or bool) array attribute to the file (root group).

The values are written as a 1-D HDF5 array attribute (simple dataspace [values.len()], on-disk type T::hdf5_type()), read back by h5py as a numpy array — the array counterpart of set_attr_numeric. For a multi-dimensional shape use set_attr_array_numeric_nd.

Source

pub fn set_attr_array_numeric_nd<T: H5Type>( &self, name: &str, values: &[T], shape: &[usize], ) -> Result<()>

Add a numeric (or bool) N-dimensional array attribute to the file (root group).

shape gives the dataspace dimensions; values is the row-major data and its length must equal the product of shape (an empty shape is a scalar, requiring exactly one value). Read back by h5py as a numpy array of that shape. set_attr_array_numeric is the 1-D convenience form.

Source

pub fn set_attr_string_array(&self, name: &str, values: &[&str]) -> Result<()>

Add a variable-length UTF-8 string array attribute to the file (root group), read back by h5py as a 1-D array of str — the array counterpart of set_attr_string. For a multi-dimensional shape use set_attr_string_array_nd.

Source

pub fn set_attr_string_array_nd( &self, name: &str, values: &[&str], shape: &[usize], ) -> Result<()>

Add a variable-length UTF-8 string N-dimensional array attribute to the file (root group).

shape gives the dataspace dimensions; values is the row-major data and its length must equal the product of shape (an empty shape is a scalar, requiring exactly one value). Read back by h5py as a numpy array of Python str with that shape. set_attr_string_array is the 1-D convenience form.

Source

pub fn set_attr_object_reference(&self, name: &str, path: &str) -> Result<()>

Add (or replace) an object-reference attribute on the file (root group) — h5py’s f.attrs['entry'] = f['/data'].ref.

path names a dataset or a group (/ is the root group) and must already exist. The attribute takes the scalar shape h5py gives a single reference; set_attr_object_references is the array form. What reaches the file is the target’s object header address, which is assigned when the file is finalized.

Source

pub fn set_attr_object_references( &self, name: &str, paths: &[&str], ) -> Result<()>

Add (or replace) a 1-D array of object references as a file-level attribute — the array counterpart of set_attr_object_reference.

Source

pub fn attr_names(&self) -> Result<Vec<String>>

Return the names of file-level (root group) attributes.

Source

pub fn attr_unreadable_reason(&self, name: &str) -> Result<Option<String>>

Why the file-level attribute name cannot be read, or None when it can be. See H5Dataset::attr_unreadable_reason.

Source

pub fn attrs_unreadable_reason(&self) -> Result<Option<String>>

Why the file-level attribute set cannot be listed, or None when it can be. See H5Dataset::attrs_unreadable_reason.

Source

pub fn attr_string(&self, name: &str) -> Result<String>

Read a file-level string attribute.

Source

pub fn superblock_extension(&self) -> SuperblockExtension

The file-level metadata carried by the superblock extension: the shared-message table, the v1 B-tree K values, the driver-info block and the file-space strategy.

Every field is None for a file written without an extension, and for a file this handle has open for writing.

Source

pub fn object_message_storage( &self, path: &str, ) -> Result<Vec<(u8, MessageStorage)>>

How the object header at path stores each message it does not hold privately, as (message type, storage) in header order.

This is the flags byte h5debug prints as <S> / <SA>, and the pointer kind beneath a shared one — the only place a file says whether a message body is the message or a reference to one held elsewhere. Read mode only.

Source

pub fn object_message_flags(&self, path: &str) -> Result<Vec<(u8, u8)>>

The flags byte of every message the object header at path holds, as (message type, flags) in header order, null and continuation messages left out.

What h5debug prints as <C>, <DS>, <S> and the rest (H5O__debug_real, H5Odbg.c:409-455): which messages the library may cache as never-changing, which it refuses to move to the shared-message heap, and which are already there. Read mode only.

Source

pub fn object_datatype_versions( &self, path: &str, ) -> Result<Vec<DatatypeNodeVersion>>

The class and version of every datatype message the object at path carries, outermost first and then depth-first through compound members, an enum’s base and an array’s base.

The version is the one part of a datatype message a decode drops, and it is not free: H5T_set_version (H5T.c:6584-6591) picks it from the file’s low libver bound and the type’s own construction, so it is what says which generation of library can read the type back. A stored-shared datatype is followed to the committed type it names, so what comes back is the version that actually describes the object.

Source

pub fn object_records_times(&self, path: &str) -> Result<bool>

Whether the object at path records its times — H5Pget_obj_track_times on the creation property list it was made with, read back from the header that answers it.

A version-2 header says so with H5O_HDR_STORE_TIMES and the four times behind it; a version-1 dataset says so by carrying an H5O_MTIME_NEW message. A version-1 group or committed datatype says nothing either way — it has nowhere to record a time — so this is false for one however it was created. Read mode only.

Source

pub fn tracked_free_space(&self) -> Result<u64>

Bytes this file’s on-disk free-space managers record as free — libhdf5’s H5Fget_freespace, and the number h5stat -S prints as “Amount of tracked free space”.

Zero for a file that persists no managers, which is every file created without H5FileOptions::file_space asking for persist. Read mode only: an open writer’s freed blocks are not on disk yet, so the two would be different questions with one name.

Source

pub fn userblock_size(&self) -> u64

Size in bytes of the userblock this file was written with — the application-owned prefix the superblock follows (H5Pget_userblock). Zero for a file without one, whichever mode the handle is in.

Source

pub fn superblock_version(&self) -> Result<u8>

This file’s on-disk superblock format version (0-3) — libhdf5’s H5F_get_info2’s super_version, read from the file’s own header rather than derived from any bound a caller asked for.

Source

pub fn libver_bound(&self) -> Result<LibverBound>

The lowest LibverBound consistent with this file’s on-disk superblock version — a view reconstructed from superblock_version, not the bound a writer may have named: LibverBound::superblock_version maps four bounds onto version 3, so a version-3 file reports LibverBound::V110 regardless of which of the four actually wrote it.

Source

pub fn is_writable(&self) -> bool

Check if the file is in write/append mode.

Source

pub fn write_vlen_strings( &self, name: &str, strings: &[&str], ) -> Result<H5Dataset>

Create a variable-length string dataset and write data.

This is a convenience method for writing h5py-compatible vlen string datasets using global heap storage. The datatype declares UTF-8, which a Rust &str always is; write_vlen_strings_ascii writes the same dataset under an ASCII declaration, the type h5py’s string_dtype("ascii") produces.

Source

pub fn write_vlen_strings_ascii( &self, name: &str, strings: &[&str], ) -> Result<H5Dataset>

Create a variable-length ASCII string dataset and write data.

The ASCII twin of write_vlen_strings, named after the DatatypeMessage::vlen_string_ascii / DatatypeMessage::vlen_string_utf8 pair it selects between. A string that is not 7-bit is rejected rather than stored under a datatype that misdescribes it, so the file reads the same in every library that trusts the declaration.

Source

pub fn write_vlen_bytes(&self, name: &str, items: &[&[u8]]) -> Result<H5Dataset>

Create a variable-length byte-array dataset and write data.

Each &[u8] becomes one element of variable length, stored as a vlen sequence of u8 in global heap storage. h5py reads it back as an array of uint8 arrays. Returns a writer-mode handle so attributes can be attached, like write_vlen_strings.

The u8 case of write_vlen_numeric.

Source

pub fn write_vlen_numeric<T: H5Type>( &self, name: &str, items: &[&[T]], ) -> Result<H5Dataset>

Create a variable-length numeric-sequence dataset and write data.

Each &[T] becomes one element of variable length, stored as a global heap object under a vlen sequence datatype over T; h5py reads the dataset back as an array of T-typed arrays, the type h5py.vlen_dtype(np.dtype(...)) produces. Sequences may have any length, including zero. Returns a writer-mode handle so attributes can be attached, like write_vlen_strings.

let file = H5File::create("v.h5").unwrap();
let a: &[i32] = &[1, 2, 3];
let b: &[i32] = &[];
file.write_vlen_numeric("data", &[a, b]).unwrap();
Source

pub fn write_vlen_strings_compressed( &self, name: &str, strings: &[&str], chunk_size: usize, pipeline: FilterPipeline, ) -> Result<H5Dataset>

Create a chunked, compressed variable-length string dataset.

Like write_vlen_strings, but stores the vlen references in chunked layout with the given filter pipeline (e.g., FilterPipeline::deflate(6) or FilterPipeline::zstd(3)). chunk_size is the number of strings per chunk.

Source

pub fn create_appendable_vlen_dataset( &self, name: &str, chunk_size: usize, pipeline: Option<FilterPipeline>, ) -> Result<H5Dataset>

Create an empty chunked vlen string dataset ready for incremental appends.

Use append_vlen_strings to add data. If pipeline is Some, chunks are compressed (e.g., Some(FilterPipeline::lz4())).

Source

pub fn append_vlen_strings(&self, name: &str, strings: &[&str]) -> Result<()>

Append variable-length strings to an existing chunked vlen string dataset.

Source

pub fn delete_dataset(&self, name: &str) -> Result<()>

Delete a dataset name, with libhdf5’s H5Ldelete semantics: a path naming a hard link removes just that link, and if a hard link still names the object whose tree name is deleted, the dataset lives on under the link. Deleting the last name unlinks the dataset on close and the file space it owned — data blocks, chunk-index structures, and the global-heap objects of variable-length values — is freed for reuse by later writes in this session (the file itself does not shrink).

Source

pub fn delete_group(&self, name: &str) -> Result<()>

Delete a group and all its child datasets/sub-groups, freeing their file space the way delete_dataset does.

Hard links reaching in from outside the deleted subtree keep their targets alive: a dataset or group named by such a link survives under the link’s path (a group brings its whole subtree with it), and a name that is itself a hard link’s path removes just that link.

Source

pub fn dataset(&self, name: &str) -> Result<H5Dataset>

Open an existing dataset by name (read mode).

Uses libhdf5’s default dataset-access properties; name others with dataset_with.

Source

pub fn dataset_with( &self, name: &str, access: DatasetAccess, ) -> Result<H5Dataset>

dataset under named dataset-access properties — H5Dopen2 with a dapl instead of H5P_DEFAULT.

Three of the properties DatasetAccess carries decide how a virtual dataset’s extent is resolved and where its sources are looked for; DatasetAccess::efile_prefix says where the raw data files of a dataset stored through an external file list are. For a dataset that is neither, this is exactly dataset.

First open wins: while any handle on that dataset is alive, a later open of it joins that open and its own access is ignored, exactly as H5Dopen2 ignores the dapl of an open that finds the dataset already in H5FO_opened (H5Dint.c:1496-1500, :1523-1528) — only the open that creates the shared info reaches H5D__virtual_init, which is where the view and the printf gap are read out of the dapl (H5Dvirtual.c:2178-2188). Once every handle is dropped the next open resolves afresh under its own properties.

libhdf5 keys that shared info on the file rather than on one H5Fopen, so there a second H5Fopen of the same path still joins the first open’s view; here each H5File is its own reader and binds independently.

§Errors

Beyond dataset’s own errors, a DatasetAccess::virtual_printf_gap of u64::MAX — libhdf5’s HSIZE_UNDEF — is refused, as H5Pset_virtual_printf_gap refuses it.

The one property a joining open may not disagree about is DatasetAccess::efile_prefix: H5D__open_name refuses an open whose expanded external file prefix differs from the open dataset’s (H5Dint.c:1533-1545), and so does this.

Source

pub fn dataset_writer(&self, name: &str) -> Result<H5Dataset>

Reopen an existing dataset by name in write mode.

dataset only works in read mode; in write mode a dataset is normally created via new_dataset. This returns a write-mode handle to a dataset created earlier in the same session, so you can attach attributes or append chunks to it without keeping the original handle around — e.g. to flush cached first/last values onto a dataset at file-close time.

§Errors

Returns Hdf5Error::NotFound if no live dataset with that name exists, and an error in read mode (use dataset).

Source

pub fn dataset_writer_with( &self, name: &str, access: DatasetAccess, ) -> Result<H5Dataset>

dataset_writer under named dataset-access properties — H5Dopen2 with a dapl instead of H5P_DEFAULT, in write mode.

The one property that reaches a write is DatasetAccess::efile_prefix: H5D__efl_write joins each slot name of an external file list against dset->shared->extfile_prefix (H5Defl.c:429-431), which the open that settled the dataset’s shared info built from its dapl. So this is how a dataset reopened from an existing file is told where its raw data files are before being written to; the other properties decide a virtual dataset’s extent, which this writer never resolves.

First open wins, and a joining open may not disagree about that prefix — see H5File::dataset_with for the same rule on the read side. A dataset this session created settled its prefix from DatasetBuilder::efile_prefix, so while its handle is alive this call must name the same one; once every handle is dropped the next call settles it afresh.

§Errors

dataset_writer’s errors, plus a refusal when access names an external file prefix that disagrees with the one an open of this dataset is still holding.

Source

pub fn dataset_names(&self) -> Vec<String>

Return the names of all datasets in the root group.

Works in both read and write mode: in write mode, returns the names of datasets created so far; in read mode, returns the names discovered during file open.

Source

pub fn named_datatype_names(&self) -> Vec<String>

The paths of every committed (named) datatype in this file.

A committed datatype is an object in its own right, in neither dataset_names nor the group listing. In write mode these are the types commit_datatype committed this session.

Source

pub fn named_datatype(&self, path: &str) -> Result<H5NamedDatatype>

Open a committed (named) datatype by path (read mode).

The handle opens whenever the object is there; a type this crate cannot decode reports why from H5NamedDatatype::datatype, so its attributes stay reachable.

§Errors

Hdf5Error::NotFound when no committed datatype is at that path.

Source

pub fn close(self) -> Result<()>

Explicitly close the file. For a writer, this finalizes the file (writes superblock, headers, etc.). For a reader, this is a no-op.

The file is also auto-finalized on drop, but calling close() lets you handle errors.

Source

pub fn close_no_sync(self) -> Result<()>

Close the file without a final fsync (write mode only).

Like close, this finalizes the file — object headers and superblock are written, so on return it is a complete, valid HDF5 file readable by any process — but the trailing sync_all (fsync) is skipped. The bytes are handed to the OS but are not guaranteed durable against power loss or an OS crash until the OS flushes its page cache.

This trades durability for speed (the fsync typically dominates close latency); use it for bulk output that can be regenerated. Prefer close when durability matters. Dropping the file without calling either finalizes durably.

For a reader or an already-closed file this is a no-op, matching close.

Source

pub fn flush(&self) -> Result<()>

Hand every byte written so far to the operating system. Only meaningful in write mode.

This empties the write accumulator, so another process reading the file afterwards sees everything written up to this point. It does not finalize the file — object headers and the superblock are still close’s work — and it does not fsync.

Auto Trait Implementations§

§

impl !RefUnwindSafe for H5File

§

impl !Send for H5File

§

impl !Sync for H5File

§

impl !UnwindSafe for H5File

§

impl Freeze for H5File

§

impl Unpin for H5File

§

impl UnsafeUnpin for H5File

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.