HDF5编程模型与接口简介

本文翻译自官方文档《Introduction to the HDF5 Programming Model and APIs》,有删减。

虽然HDF5应用编程接口很复杂,但是通常情况下,你只需要了解几个简单的函数就可以实现你的大部分工作了。下面通过Python和C的示例来说明这个编程模型,Python示例使用h5py实现。

在运行示例程序前,以下几点需要特别注意:

(1)我们可以从遵从H5*形式的C函数(其中*是一个单个字母)中推断该函数可以操作的对象类型(FORTRAN也类似,以h5*开头,以_f结尾):

文件H5Fopen(C)、h5fopen_f(FORTRAN)

数据集H5Dopen(C)、h5dopen_f(FORTRAN)

数据空间H5Sclose(C)、h5sclose_f(FORTRAN)

(2)为了可移植性,HDF5库有自己定义的类型。一些常见的类型:

hid_t是一种文件句柄,例如,打开文件、打开数据空间对应的返回值都是这个类型。

hsize_t是HDF5自己定义的一种类型,用于指定维度,可以看做HDF5的size_t

herr_t是很多函数的返回值类型,可以根据该值确定操作的状态。

(3)运行示例程序必须导入库文件:

Python:import h5py/import numpy

C:#include hdf5.h

FORTRAN:USE HDF5

创建文件

创建文件的步骤:

(1)指定一个性质列表(或者使用默认值)

(2)创建文件

(3)关闭文件

下面的例子分别使用Python和C创建一个名为file.h5的文件,然后关闭它。该文件只有一个根组。

创建文件

Python:

import h5py
# 使用写入模式打开一个新的HDF5文件,返回一个文件句柄
file = h5py.File('file.h5', 'w')
# 使用完该文件句柄,你必须关闭它
file.close()

C:

#include "hdf5.h"
int main() {
  /* 打开一个HDF5文件
   * H5F_ACC_TRUNC:以写的形式打开,如果该文件存在,则清空该文件
   * H5P_DEFAULT:使用默认性质
   */
  hid_t file_id = H5Fcreate("file.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  // 关闭该文件
  herr_t status = H5Fclose(file_id);
  return 0;
}

创建数据集

一个HDF5数据集包含数据和对数据的描述(数据类型、数据空间、性质、属性等),一般情况下,创建数据集你需要:

(1)创建对数据集的描述信息。

(2)决定该数据集属于哪个组。

(3)创建数据集。

(4)关闭数据集的句柄。

下面的例子演示如何创建一个4x6的整型数据集dset,并保存到文件dset.h5中。dset直接保存在根组中。

创建数据集

Python:

import h5py
file = h5py.File('dset.h5', 'w')
# 创建一个4x6的数据集,其类型为大端32位整型
file.create_dataset('dset', (4, 6), h5py.h5t.STD_I32BE)
file.close()

C:

#include "hdf5.h"
int main() {
  hid_t file_id = H5Fcreate("dset.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  // 创建一个hsize_t类型的数组,该数组用于指定数据空间大小
  hsize_t dims[2] = {4, 6};
  // 创建一个数据空间
  hid_t dataspace_id = H5Screate_simple(2, dims, NULL);
  // 在该空间下使用默认性质创建一个元素类型为大端32位的数据集
  hid_t dataset_id = H5Dcreate(file_id, "/dset", H5T_STD_I32BE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  // 关闭数据集
  H5Dclose(dataset_id);
  // 关闭数据空间
  H5Sclose(dataspace_id);
  H5Fclose(file_id);
  return 0;
}

读写数据集

Python:

import h5py
import numpy as np
file = h5py.File('dset.h5', 'w')
dataset = file.create_dataset('dset', (4, 6), h5py.h5t.STD_I32BE)
# 创建一个4x6的数组
data = np.zeros((4, 6))
for i in range(4):
  for j in range(6):
    data[i][j] = i * 6 + j + 1;
# 写入数据
dataset[...] = data
# 读取数据
data_read = dataset[...]
file.close()

C:

#include "hdf5.h"
int main() {
  hid_t file_id = H5Fcreate("dset.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  hsize_t dims[2] = {4, 6};
  hid_t dataspace_id = H5Screate_simple(2, dims, NULL);
  hid_t dataset_id = H5Dcreate(file_id, "/dset", H5T_STD_I32BE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  // 创建一个4x6的数组
  int dset_data[4][6];
  for (int i=0; i<4; ++i) {
    for (int j=0; j<6; ++j) {
      dset_data[i][j] = i * 6 + j + 1;
    }
  }
  // 写入,H5ALL代表是写入到整个数据集而不是子集
  H5Dwrite(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset_data);
  // 读取
  int dset_data_read[4][6];
  H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset_data_read);
  printf("dset_data_read[1][2] = %d\n", dset_data_read[1][2]);
  H5Dclose(dataset_id);
  H5Sclose(dataspace_id);
  H5Fclose(file_id);
  return 0;
}

创建组

创建组之前,你必须先确定该组的父组的位置编号,步骤如下:

(1)确定该组的父组位置编号(例如根组),并打开该组。

(2)定义性质,也可以使用默认性质。

(3)创建组。

(4)关闭组。

下面的例子演示了如何在根组下创建一个名为MyGroup的组。

创建组

Python:

import h5py
file = h5py.File('dset.h5', 'w')
# 创建组
group = file.create_group ('MyGroup')
file.close()

C:

#include "hdf5.h"
int main() {
  hid_t file_id = H5Fcreate("dset.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    // 创建组
    hid_t group_id = H5Gcreate(file_id, "MyGroup", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    // 关闭组
    H5Gclose(group_id);
    H5Fclose(file_id);
  return 0;
}

创建和写入属性

创建属性前,你必须打开该属性需要绑定的对象,步骤如下:

(1)打开需要绑定的对象。

(2)创建属性。

(3)写入属性。

(4)关闭属性和对象。

下面的例子演示了如何给数据集dset绑定属性:

创建并写入属性

Python:

import h5py
import numpy as np
file = h5py.File('dset.h5', 'w')
dataset = file.create_dataset('dset', (4, 6), h5py.h5t.STD_I32BE)
# 创建字符串属性
dataset.attrs['Units'] = 'Meters per second'
# 创建整型属性
attr_data = np.zeros((2,))
attr_data[0] = 100
attr_data[1] = 200
dataset.attrs.create('Speed', attr_data, (2,), 'i')
file.close()

C:

#include "hdf5.h"
int main() {
  hid_t file_id = H5Fcreate("dset.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  hsize_t dims = 2;
  hid_t dataspace_id = H5Screate_simple(1, &dims, NULL);
  hid_t dataset_id = H5Dcreate(file_id, "/dset", H5T_STD_I32BE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  // 创建属性
  hid_t attribute_id = H5Acreate2(dataset_id, "Units", H5T_STD_I32BE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
  // 写入属性
  int attr_data[2] = {100, 200};
  H5Awrite(attribute_id, H5T_NATIVE_INT, attr_data);
  // 关闭属性
  H5Aclose(attribute_id);
  H5Dclose(dataset_id);
  H5Sclose(dataspace_id);
  H5Fclose(file_id);
  return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容