Working with files¶
Todo
For the time being, h5cpp provides no interface to the metadata cache. This feature might be added in future.
The first things you have to do when using HDF5 is to create a new file or
open an already existing one. This chapter deals with this very basic topic.
Unlike in the C-API filenames are not represented by mere strings but by
instances of boost::filesystem::path
. This avoids problems
when using different seperator characters in a path on different platforms.
Additionally a file system path has a particular semantic which is not
reflecetd by a simple string.
Identifying an HDF5 file¶
Before opening an HDF5 file we should check whether or not the filesystem object
referenced by boost::filesystem::path
is indeed an HDF5 file.
The simpliest way to achieve this goal is to use the
hdf5::file::is_hdf5_file()
utiltiy function function.
boost::filesystem::path file_path = ...;
if(!hdf5::file::is_hdf5_file(file_path))
{
//deal with the error situation
}
//continue with opening the file
Creating files¶
The first thing one may wants to do is to create a new file. Use the
hdf5::file::create()
function
#include <h5cpp/hdf5.hpp>
#include <boost/filesystem.hpp>
using namespace hdf5;
using namespace fs = boost::filesystem;
int main()
{
//creating a new file
fs::path file_path("data.h5");
file::File f1 = file::create(file_path);
//do something with the file
}
By default, the hdf5::file::create()
function will throw an
exception if the file already exists. To overwrite an already existing file
use
file::File f1 = file::create(file_path,file::AccessFlags::Truncate);
HDF5 uses property lists to pass additional information to API functions.
The hdf5::file::create()
function accepts two additional arguments
a reference to a file creation property list (
hdf5::property::FileCreateList
)and a reference to a file access property list (
hdf5::property::FileAccessList
)
There are several situations when you have to use these property lists to create a file. The most common might be
you want better control over object and link iteration
you want to use the SWMR feature introduced with HDF5 1.10.
We will deal with the iterator problem a bit later. For now we have a look on the SWMR feature. Provided you link h5cpp against HDF5 1.10.0 or higher you have to provide a custom file access property list
property::FileCreationList fcpl; //can use the default here
property::FileAccessList fapl;
//we need to set the appropriate version flags
fapl.library_version_bounds(property::LibVersion::Latest,
property::LibVersion::Latest);
file::File f = file::create("swmr_file.h5",
file::AccessFlags::Truncate,
fcpl,fapl);
Opening an existing file¶
To open a file use the hdf5::file::open()
function
#include <h5cpp/hdf5.hpp>
#include <boost/filesystem.hpp>
using namespace hdf5;
using namespace fs = boost::filesystem;
int main()
{
//creating a new file
fs::path file_path("data.h5");
file::File f1 = file::open(file_path);
//do something with the file
}
By default, files are opened in read only mode to avoid accidental modification of the file. To write to an existing file use
file::File f1 = file::open(file_path,file::AccessFlags::ReadWrite);
The only additional argument hdf5::file::open()
takes is a
reference to file access property list. We have to use this to open a file
for SWMR access. However, in addition we need some custom flags to use
SWMR. To open a file for writing in SWMR mode use
property::FileAccessList fapl;
//we need to set the appropriate version flags
fapl.library_version_bounds(property::LibVersion::Latest,
property::LibVersion::Latest);
file::File write_fiel = file::open(file_path,
file::AccessFlags::ReadWrite |
file::AccessFlags::SWMRWrite,
fapl);
and to open a file for reading in SWMR mode use
property::FileAccessList fapl;
//we need to set the appropriate version flags
fapl.library_version_bounds(property::LibVersion::Latest,
property::LibVersion::Latest);
file::File write_fiel = file::open(file_path,
file::AccessFlags::ReadOnly |
file::AccessFlags::SWMRRead,
fapl);
Getting access to the object tree¶
Unlike in the C-API an instance of hdf5::File
is not a valid
parent object. For this purpose the root group of the file must be obtained
using the File::root()
method of a file instance
hdf5::file::File f = ....;
hdf5::node::Group root_group = f.root();
Rational
Though in the C-API the ID of a group and a file can both act as valid
parent object, this approach does not run well with an object oriented
appraoch. It would mean that hdf5::file::File
and hdf5::node::Gruop
would have to provide a common,
group-like interface.
In order to avoid code duplications we hdf5::file::File
would have to derive from hdf5::node::Group
making it
also a valid group object. From the point of semantics this is simply
wrong. A file is not a group.
Though the approach choosen here requires a single line of code more to
obtain the root group of a file before doing any useful work on the file,
however, I think a clean difference between hdf5::file::File
and hdf5::node::Group
is worth the additional effort.