本文翻译自官方文档《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;
}