分类 HDF5 下的文章

HDF5: C++ 类封装(创建、写入操作)


简介

直接用c的代码写呢太麻烦,用官网的c++用例写呢还乱码,逼得我只能自己写个类来处理了,要不写的东西太多,c的太繁琐,所以自己封装个类方便调用。

hdf5 封装c++ 类

  • #ifndef _OPEN_HDF5_
  • #define _OPEN_HDF5_
  • #include <iostream>
  • #include <string>
  • #include <vector>
  • #include <typeinfo>
  • #include "h5Cpp.h"
  • using namespace std;
  • struct H5TITLE{
  • string name;
  • string type;
  • };
  • /******** ATTR ********/
  • class CRattr
  • {
  • private:
  • hid_t hand_id;
  • public:
  • CRattr(hid_t id){
  • hand_id = id;
  • };
  • ~CRattr(){};
  • template <class T>
  • shared_ptr<CRattr> attr(string key, T value, int len=1){
  • hid_t attr_type, attr_space;
  • hsize_t attr_dims[1] = { len };
  • char* value2 = new char(len);
  • if(typeid(T) == typeid(string) || typeid(T) == typeid(char*)){
  • attr_type = H5Tcopy(H5T_C_S1);
  • H5Tset_size(attr_type, H5T_VARIABLE);
  • }else if(typeid(T) == typeid(int)){
  • attr_type = H5T_NATIVE_INT;
  • }else if(typeid(T) == typeid(double)){
  • attr_type = H5T_NATIVE_DOUBLE;
  • }else{
  • return NULL;
  • }
  • attr_space = H5Screate_simple(1, attr_dims, NULL);
  • hid_t attr = H5Acreate(hand_id, key.c_str(), attr_type, attr_space, H5P_DEFAULT, H5P_DEFAULT);
  • if(typeid(T) == typeid(string) || typeid(T) == typeid(char*)){
  • H5Awrite(attr, attr_type, value2);
  • }else{
  • H5Awrite(attr, attr_type, value);
  • }
  • shared_ptr<CRattr> tmp = make_shared<CRattr>(hand_id);
  • return tmp;
  • }
  • };
  • /******** DATA ********/
  • class CRdata
  • {
  • private:
  • hid_t hand_id;
  • string dataset_name;
  • public:
  • CRdata(hid_t id, string name){
  • hand_id = id;
  • dataset_name = name;
  • };
  • ~CRdata(){};
  • template <class T>
  • shared_ptr<CRattr> insert(int len, T* wdata, vector<H5TITLE> &title){
  • herr_t status;
  • hsize_t dims[1] = { len };
  • hid_t memtype, space, dset, strtype = H5Tcopy(H5T_C_S1);
  • status = H5Tset_size(strtype, H5T_VARIABLE);
  • status = H5Tset_cset(strtype, H5T_CSET_UTF8);
  • memtype = H5Tcreate(H5T_COMPOUND, sizeof(T));
  • int sizet = 0;
  • for (int i = 0; i < title.size(); i++)
  • {
  • if (title.at(i).type == "string" || title.at(i).type == "char") {
  • H5Tinsert(memtype, title.at(i).name.c_str(), sizet, strtype);
  • } else if (title.at(i).type == "double") {
  • H5Tinsert(memtype, title.at(i).name.c_str(), sizet, H5T_NATIVE_DOUBLE);
  • } else if (title.at(i).type == "int") {
  • H5Tinsert(memtype, title.at(i).name.c_str(), sizet, H5T_NATIVE_INT);
  • }
  • sizet += sizeof(char*);
  • }
  • space = H5Screate_simple(1, dims, NULL);
  • // 创建数据集
  • dset = H5Dcreate(hand_id, dataset_name.c_str(), memtype, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  • // 插入数据
  • status = H5Dwrite(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
  • shared_ptr<CRattr> tmp = make_shared<CRattr>(dset);
  • return tmp;
  • };
  • template <class T>
  • shared_ptr<CRattr> insertList(int rows, int cols, T* wdata){
  • hid_t space, dset;
  • hid_t memtype;
  • if (typeid(T) == typeid(double)) {
  • memtype = H5T_NATIVE_DOUBLE;
  • } else if (typeid(T) == typeid(long double)){
  • memtype = H5T_NATIVE_LDOUBLE;
  • } else {
  • memtype = H5T_NATIVE_INT;
  • }
  • hsize_t dims[] = { rows, cols };
  • space = H5Screate_simple(2, dims, NULL);
  • // 创建数据集
  • dset = H5Dcreate(hand_id, dataset_name.c_str(), memtype, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  • // 插入数据
  • herr_t status = H5Dwrite(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
  • shared_ptr<CRattr> tmp = make_shared<CRattr>(dset);
  • return tmp;
  • };
  • };
  • /******** GROUP ********/
  • class CRgroup
  • {
  • private:
  • hid_t hand_id;
  • public:
  • CRgroup(hid_t id){
  • hand_id = id;
  • };
  • ~CRgroup(){};
  • shared_ptr<CRgroup> gopen(string group_name){
  • hid_t group_id = H5Gcreate(hand_id, group_name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  • shared_ptr<CRgroup> tmp = make_shared<CRgroup>(group_id);
  • return tmp;
  • };
  • shared_ptr<CRdata> dataset(string dataset_name){
  • shared_ptr<CRdata> tmp = make_shared<CRdata>(hand_id, dataset_name);
  • return tmp;
  • };
  • template <class T>
  • shared_ptr<CRattr> attr(string key, T* value, int len = 1){
  • shared_ptr<CRattr> tmp = make_shared<CRattr>(hand_id);
  • tmp->attr<T>(key, value, len);
  • return tmp;
  • }
  • };
  • /******** FILE ********/
  • class CRfile
  • {
  • private:
  • hid_t hand_id;
  • public:
  • CRfile(string file_name){
  • hand_id = H5Fcreate(file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  • };
  • ~CRfile(){};
  • shared_ptr<CRgroup> gopen(string group_name){
  • shared_ptr<CRgroup> tmp = make_shared<CRgroup>(hand_id);
  • return tmp.gopen(group_name);
  • };
  • shared_ptr<CRdata> dataset(string dataset_name){
  • shared_ptr<CRdata> tmp = make_shared<CRdata>(hand_id, dataset_name);
  • return tmp;
  • };
  • hid_t getHand() {
  • return hand_id;
  • }
  • };
  • #endif

封装的使用示例

  • struct mtx{
  • double x;
  • double y;
  • string z;
  • };
  • struct mt{
  • double x;
  • double y;
  • char* z;
  • };
  • struct mtx mtt1[5];
  • for (int i = 0; i < 5; i++)
  • {
  • mtt1[i].x = i;
  • mtt1[i].y = i;
  • mtt1[i].z = "test";
  • }
  • struct mt mtt2[5];
  • for (int i = 0; i < 5; i++)
  • {
  • mtt2[i].x = mtt1[i].x;
  • mtt2[i].y = mtt1[i].y;
  • mtt2[i].z = (char*)mtt1[i].z.c_str();
  • }
  • double wdata[4] = {1,2,3,4};
  • Rfile test("test.h5");
  • struct mt *wdata2 = new struct mt[5];
  • vector<H5TITLE> title = {{"X","double"},{"Y","double"},{"Z","char"}};
  • for (int i = 0; i < 5; i++)
  • {
  • wdata2[i].x = mtt1[i].x;
  • wdata2[i].y = mtt1[i].y;
  • wdata2[i].z = (char*)mtt1[i].z.c_str();
  • }
  • test.gopen("gtest").gopen("gtest2").dataset("dset").insertList<double>(2,2,wdata);
  • int value[1] = {1};
  • test.dataset("dtest").insert<mt>(5, wdata2, title).attr<int>("Name", value, 1);
  • test.gopen("att").attr<int>("test", value, 1).attr<int>("test2", value, 1);

图示

微信图片编辑_20211129145125.jpg


HDF5: C 用例(创建、写入操作)


介绍

官网很多用例测试,但是全英的优点费劲,这里就将示例总结一下,提高用例的可读性,希望能帮助大家快速上手HDF5.

相关函数及作用

函数名作用
H5Fcreate创建HDF5文件
H5Gcreate创建组

用例代码及说明

  • #include <iostream>
  • #include <string>
  • #include "H5Cpp.h"
  • #pragma execution_character_set("utf-8")
  • #define FILE "h5ex_t_cmpd.h5"
  • #define DATASET "DS1"
  • #define DIM0 10
  • using namespace std;
  • struct sensor_r{
  • string location1;
  • string location2;
  • string location3;
  • string location4;
  • string location5;
  • string location6;
  • string location7;
  • int serial_no;
  • string location;
  • double temperature;
  • double pressure;
  • };
  • typedef struct {
  • char *location1;
  • char *location2;
  • char *location3;
  • char *location4;
  • char *location5;
  • char *location6;
  • char *location7;
  • int serial_no;
  • char *location;
  • double temperature;
  • double pressure;
  • } sensor_t; /* Compound type */
  • int
  • main (void)
  • {
  • hid_t file, filetype, memtype, strtype, space, dset;
  • /* Handles */
  • herr_t status;
  • hsize_t dims[1] = {DIM0};
  • int ndims,
  • i;
  • sensor_r rdata[DIM0];
  • for (int i = 0; i < DIM0; i++)
  • {
  • rdata[i].location1 = "test";
  • rdata[i].location2 = "test中文";
  • rdata[i].location3 = "test";
  • rdata[i].location4 = "test";
  • rdata[i].location5 = "test";
  • rdata[i].location6 = "test";
  • rdata[i].location7 = "test";
  • rdata[i].serial_no = i;
  • rdata[i].location = "test123中文";
  • rdata[i].temperature = i;
  • rdata[i].pressure = 2.0;
  • }
  • sensor_t * wdata = new sensor_t[DIM0];
  • for (int i = 0; i < DIM0; i++)
  • {
  • wdata[i].location1 = (char*)rdata[i].location1.c_str();
  • wdata[i].location2 = (char*)rdata[i].location2.c_str();
  • wdata[i].location3 = (char*)rdata[i].location3.c_str();
  • wdata[i].location4 = (char*)rdata[i].location4.c_str();
  • wdata[i].location5 = (char*)rdata[i].location5.c_str();
  • wdata[i].location6 = (char*)rdata[i].location6.c_str();
  • wdata[i].location7 = (char*)rdata[i].location7.c_str();
  • wdata[i].serial_no = i;
  • wdata[i].location = (char*)rdata[i].location.c_str();
  • wdata[i].temperature = i;
  • wdata[i].pressure = 2.0;
  • cout << wdata[i].location2 << endl;
  • }
  • /*
  • * Create a new file using the default properties.
  • */
  • file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  • /*
  • * Create variable-length string datatype.
  • */
  • strtype = H5Tcopy (H5T_C_S1);
  • status = H5Tset_size (strtype, H5T_VARIABLE);
  • /*
  • * Create the compound datatype for memory.
  • */
  • memtype = H5Tcreate (H5T_COMPOUND, sizeof (sensor_t));
  • status = H5Tinsert (memtype, "Location1", HOFFSET (sensor_t, location1),strtype);
  • status = H5Tinsert (memtype, "Location2", HOFFSET (sensor_t, location2),strtype);
  • status = H5Tinsert (memtype, "Location3", HOFFSET (sensor_t, location3),strtype);
  • status = H5Tinsert (memtype, "Location4", HOFFSET (sensor_t, location4),strtype);
  • status = H5Tinsert (memtype, "Location5", HOFFSET (sensor_t, location5),strtype);
  • status = H5Tinsert (memtype, "Location6", HOFFSET (sensor_t, location6),strtype);
  • status = H5Tinsert (memtype, "Location7", HOFFSET (sensor_t, location7),strtype);
  • status = H5Tinsert (memtype, "Serial number",HOFFSET (sensor_t, serial_no), H5T_NATIVE_INT);
  • status = H5Tinsert (memtype, "Location", HOFFSET (sensor_t, location),strtype);
  • status = H5Tinsert (memtype, "Temperature (F)", HOFFSET (sensor_t, temperature), H5T_NATIVE_DOUBLE);
  • status = H5Tinsert (memtype, "Pressure (inHg)", HOFFSET (sensor_t, pressure), H5T_NATIVE_DOUBLE);
  • /*
  • * Create dataspace. Setting maximum size to NULL sets the maximum
  • * size to be the current size.
  • */
  • space = H5Screate_simple (1, dims, NULL);
  • /*
  • * Create the dataset and write the compound data to it.
  • */
  • dset = H5Dcreate (file, DATASET, memtype, space, H5P_DEFAULT, H5P_DEFAULT,
  • H5P_DEFAULT);
  • status = H5Dwrite (dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
  • /*
  • * Close and release resources.
  • */
  • status = H5Dclose (dset);
  • status = H5Sclose (space);
  • status = H5Tclose (memtype);
  • status = H5Fclose (file);
  • return 0;
  • }

HDF5: 介绍


一、HDF5简介

HDF 是用于存储和分发科学数据的一种自我描述、多对象文件格式。HDF 是由美国国家超级计算应用中心(NCSA)创建的,以满足不同群体的科学家在不同工程项目领域之需要。HDF 可以表示出科学数据存储和分布的许多必要条件。HDF 被设计为:

  1. 自述性:对于一个HDF 文件里的每一个数据对象,有关于该数据的综合信息(元数据)。在没有任何外部信息的情况下,HDF 允许应用程序解释HDF文件的结构和内容。
  2. 通用性:许多数据类型都可以被嵌入在一个HDF文件里。例如,通过使用合适的HDF 数据结构,符号、数字和图形数据可以同时存储在一个HDF 文件里。
  3. 灵活性:HDF允许用户把相关的数据对象组合在一起,放到一个分层结构中,向数据对象添加描述和标签。它还允许用户把科学数据放到多个HDF 文件里。
  4. 扩展性:HDF极易容纳将来新增加的数据模式,容易与其他标准格式兼容。
    跨平台性:HDF 是一个与平台无关的文件格式。HDF 文件无需任何转换就可以在不同平台上使用。

1. HDF5的组织结构

  • File 文件。相当于根目录
  • Groups 组。类似于文件夹
  • Datasets 数据集。数据的集合
  • Dataspace 数据空间给出原始数据的秩 (Rank) 和维度 (dimension)
  • Datatype 数据类型
  • Properties 说明该 dataset 的分块储存以及压缩情况
  • Chunked: 待摸索
  • Chunked & Compressed: 待摸索
  • Attributes 为该 file/gourps/dataset 的其他自定义属性

hdf5_1.jpg
hdf5_2.jpg
hdf5_3.jpg

2. 相关网站

HDF5官网
HDF5 View 下载地址
HDF5 相关下载地址
官方文档地址

二、HDF5下载与安装

1. cmake形式引入

待完善

2. window下安装

下载官方安装包直接安装或下载下方压缩包(官网下载需要登录,内陆访问很慢)

hdf5-1.12.1-Std-win10_64-vs16.zip

3. linux下安装

待完善