我将博客迁到 GitHub pages 了。本文有些纰漏,请前往 pages 查看。
概述
HDF5是一种跨平台存储(高维)数组的数据格式。HDF5有多种语言的绑定,其中包括C++。在这里我记录了各种踩坑后如何将数据读入C++。
读标量
// 注意头文件不是 hdf5.h
#include "H5Cpp.h"
//#include <iostream>
int main()
{
H5::H5File file("/path/to/data.h5", H5F_ACC_RDONLY);
H5::DataSet dataset = file.openDataSet("dataset/path");
H5::DataSpace filespace = dataset.getSpace();
hsize_t shape[1]; // 此处不确定,不过长度设为 1 肯定是足够了
int _dims = filespace.getSimpleExtentDims(shape); // _dims 一定为 0
double buf[1];
dataset.read(buf, H5::PredType:NATIVE_DOUBLE, mspace, filespace);
// 读出来啦
//std::cout << buf[0] << std::endl;
return 0;
// file 和 dataset 会被它们的析构函数关闭
}
读向量到数组
#include "H5Cpp.h"
//#include <iostream>
int main()
{
H5::H5File file("/path/to/data.h5", H5F_ACC_RDONLY);
H5::DataSet dataset = file.openDataSet("dataset/path");
H5::DataSpace filespace = dataset.getSpace();
hsize_t shape[1]; // `1' 应被替换成相应维数,例如矩阵应写作 `2'
// 返回的 _dim 是实际维数,如果你没记错的话应该和上一行填的相同
int _dims = filespace.getSimpleExtentDims(shape);
// 现在 shape 的前 _dim 个元素是向量形状了
double *buf = new double[shape[0]]; // 如果是矩阵的话应分配 shape[0]*shape[1] 的空间
dataset.read(buf, H5::PredType::NATIVE_DOUBLE, mspace, filespace);
// 读出来啦
// for 循环打印 buf,此处略过
delete[] buf;
return 0;
}
注意向量是连续存储的,不能用例如 double cbuf[M][N]
二维数组去读例如矩阵。见此回答。
读向量到 std::vector
基本相同:
#include "H5Cpp.h"
#include <vector>
//#include <iostream>
int main()
{
H5::H5File file("/path/to/data.h5", H5F_ACC_RDONLY);
H5::DataSet dataset = file.openDataSet("dataset/path");
H5::DataSpace filespace = dataset.getSpace();
hsize_t shape[1]; // `1' 应被替换成相应维数,例如矩阵应写作 `2'
// 返回的 _dim 是实际维数,如果你没记错的话应该和上一行填的相同
int _dims = filespace.getSimpleExtentDims(shape);
// 现在 shape 的前 _dim 个元素是向量形状了
std::vector<double> buf(shape[0]); // 如果是矩阵的话应分配 shape[0]*shape[1] 的空间
dataset.read(buf.data(), H5::PredType::NATIVE_DOUBLE, mspace, filespace);
// 读出来啦
// for 循环打印 buf,此处略过
return 0;
}
编译选项
此处只涉及 Linux/Darwin 的选项,不是很清楚 Windows 怎么编译。Makefile 如下:
LDFLAGS = \
-L/path/to/hdf5/incstall/directory/lib
# 注意这里链接库的名称,不是光一个 -lhdf5 就行了的
LDLIBS = \
-lhdf5 \
-lhdf5_cpp \
-lhdf5_hl_cpp
CPPFLAGS = \
-I/path/to/hdf5/install/directory/include
CXX = clang++
# `-std=c++11' 应该是可选的,不过我的运行环境如此,没试过不加会怎样
a.out : source.cpp
$(CXX) $(CPPFLAGS) $(LDFLAGS) -std=c++11 -o $@ $^ $(LDLIBS)