Skip to content

Commit

Permalink
Merge branch 'documentation'
Browse files Browse the repository at this point in the history
  • Loading branch information
eugenwintersberger committed Nov 1, 2017
2 parents fefe7a2 + 1923eae commit f7274e6
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 90 deletions.
3 changes: 2 additions & 1 deletion doc/source/users_guide/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set(SOURCES index.rst
using.rst)
using.rst
files.rst)

add_sphinx_source(${SOURCES})
copy_to_current_build(${SOURCES})
236 changes: 148 additions & 88 deletions doc/source/users_guide/files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,128 +8,188 @@ Working with files
.. todo::

How do we deal with the meta-data cache?

Open and create files
=====================

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 :cpp:class:`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 object
referenced by :cpp:class:`boost::filesystem::path` is indeed an HDF5 file.
The simpliest way to achieve this goal is to use the
:cpp:func:`hdf5::file::is_hdf5_file` utiltiy function function.

.. code-block:: cpp
using namespace fs = boost::filesystem;
//creating a new file
fs::path file_path("name.h5");
h5::file_t f1 = h5::file_t::create(file_path,
h5::file_t::flag_t::TRUNCATE,
file_creation_plist(),
file_access_plist());
//opening an existing file
h5::file_t f2 = h5::file_t::open(file_path,
h5::file_t::flag_t::READ_WRITE,
file_access_plist());
Unlike in the C-API an instance of :cpp:class:`h5::file_t` is not a valid parent object.
For this purpose the root group of the file must be obtained using the
:cpp:func:`root()` method of a file instance
boost::filesystem::path file_path = ...;
if(!hdf5::file::is_hdf5_file(file_path))
{
//deal with the error situation
}
//continue with opening the file
.. code-block:: cpp
Creating files
==============

h5::group_t root_group = f.root();
The first thing one may wants to do is to create a new file. Use the
:cpp:func:`hdf5::file::create` function

.. admonition:: Rational
.. code-block:: cpp
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 :cpp:class:`file_t` and :cpp:class:`group_t`
would have to provide a common, group-like interface.
#include <h5cpp/hdf5.hpp>
#include <boost/filesystem.hpp>
In order to avoid code duplications we :cpp:class:`file_t` would have to
derive from :cpp:class:`group_t` making it also a valid group object. From
the point of semantics this is simply wrong. A file is not a group.
using namespace hdf5;
using namespace fs = boost::filesystem;
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 :cpp:class:`file_t` and
:cpp:class:`group_t` is worth the additional effort.
int main()
{
//creating a new file
fs::path file_path("data.h5");
file::File f1 = file::create(file_path);
Methods
=======
//do something with the file
}
By default, the :cpp:func:`hdf5::file::create` function will throw an
exception if the file already exists. To overwrite an already existing file
use

.. cpp:class:: file_t
.. code-block:: cpp
.. cpp:enum-struct:: flag_t : uint8_t
file::File f1 = file::create(file_path,file::AccessFlags::TRUNCATE);
HDF5 uses property lists to pass additional information to API functions.
The :cpp:func:`hdf5::file::create` function accepts two additional arguments

* a reference to a file creation property list
(:cpp:class:`hdf5::property::FileCreateList`)
* and a reference to a file access property list
(:cpp:class:`hdf5::property::FileAccessList`)

There are several situations when you have to use these property lists to
create a file. The most common might be

.. cpp:function:: public boost::filesystem_path path() const
Return the file system path for this instance of :cpp:class:`file_t`.
* 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

.. cpp:function:: public void flush() const
.. code-block:: cpp
Flush data to the file.
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 :cpp:func:`hdf5::file::open` function

.. cpp:function:: public flag_t mode() const
.. code-block:: cpp
Return the current mode the file is opened.
#include <h5cpp/hdf5.hpp>
#include <boost/filesystem.hpp>
.. cpp:function:: public group_t root() const
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);
Return the root group of the file as an instance of
:cpp:class:`group_t`.
//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

.. code-block:: cpp
file::File f1 = file::open(file_path,file::AccessFlags::READWRITE);
The only additional argument :cpp:func:`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

Flags
=====
.. code-block:: cpp
The :cpp:class:`file_t` class has a nested scoped enumeration type
:cpp:enum:`file_t::flags` with flags used to open and create files as well as
to denote the status of a file.
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::SWMR_WRITE,
fapl);
and to open a file for reading in SWMR mode use

+----------------------------------------------+------------------------------+
| Flag | Description |
+==============================================+==============================+
| :cpp:enumerator:`file_t::flag_t::TRUNCATE` | overwrite an already existing|
| | file during file creation! |
+----------------------------------------------+------------------------------+
| :cpp:enumerator:`file_t::flag_t::EXCL` | file creation will fail if a |
| | file of equal name already |
| | exists |
+----------------------------------------------+------------------------------+
| :cpp:enumerator:`file_t::flag_t::READ_WRITE` | open a file for read write |
| | access or the file is in |
| | read write mode |
+----------------------------------------------+------------------------------+
| :cpp:enumerator:`file_t::flag_t::READ_ONLY` | open a file in read only mode|
| | or the file is in read only |
| | mode |
+----------------------------------------------+------------------------------+
| :cpp:enumerator:`file_t::flag_t::SWMR_WRITE` | open the file in SWMR write |
| | mode or the file is in SWMR |
| | write mode |
+----------------------------------------------+------------------------------+
| :cpp:enumerator:`file_t::flag_t::SWMR_READ` | open a file in SWMR read mode|
| | or the file is in SWMR read |
| | mode. |
+----------------------------------------------+------------------------------+
.. code-block:: cpp
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::SWMR_READ,
fapl);
Utility types and functions
===========================
Getting access to the object tree
=================================

The function :cpp:func:`is_hdf5_file` checks whether or not a file system path
points to an HDF5 file or not.
Unlike in the C-API an instance of :cpp:class:`hdf5::File` is not a valid
parent object. For this purpose the root group of the file must be obtained
using the :cpp:func:`File::root()` method of a file instance

.. code-block:: cpp
boost::filesystem::path file_path = ...;
hdf5::file::File f = ....;
hdf5::node::Group root_group = f.root();
if(!h5::is_hdf5_file(file_path))
{
std::cerr<<"Some error message!"<<std::endl;
return 1;
}
.. admonition:: 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 :cpp:class:`hdf5::file::File`
and :cpp:class:`hdf5::node::Gruop` would have to provide a common,
group-like interface.

In order to avoid code duplications we :cpp:class:`hdf5::file::File`
would have to derive from :cpp:class:`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 :cpp:class:`hdf5::file::File`
and :cpp:class:`hdf5::node::Group` is worth the additional effort.


sdfsdfdsf werwer wesdf


3 changes: 2 additions & 1 deletion doc/source/users_guide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ Still need to add a table of contents here.
.. toctree::
:maxdepth: 1

using
using
files

0 comments on commit f7274e6

Please sign in to comment.