发现官网还是很好的学习资源, 关于C和C++版本的.
不断追加输出时间演化类型数据, 要注意几个点:
- 创建的最大数据空间必须有一个维度足够大或者不设限制
maxdims[0] = H5S_UNLIMITED;
maxdims[1] = U.size();
dimsf[0] = 1;
dimsf[1] = U.size();
dataspace = H5Screate_simple(RANK, dimsf, maxdims);
- 将数据集的访问权限设置为开启chunking
/* Modify dataset creation properties, i.e. enable chunking */
property = H5Pcreate(H5P_DATASET_CREATE);
hsize_t chunk_dims[2] = {1, U.size()};
status = H5Pset_chunk(property, RANK, chunk_dims);
完整代码:
#include "hdf5.h"
#include <vector>
#include <string>
#include <iostream>
#include <cassert>
using namespace std;
using std::cout, std::endl;
int saveVec2HDF5_inside(int file, std::vector<double> &U, std::string varname, int mode)
{ // HDF5 version = 1.8.21
int RANK = 2; /* RANK is Represents the dimension of the data space*/
hsize_t num_slices; /* The number of time slices*/
hid_t dataset; /* dataset handles */
hid_t datatype; /* datatype handles*/
hid_t dataspace; /* dataspace handles*/
hid_t memspace; /* dataspace handles*/
hid_t property; /* property handles*/
hsize_t dimsf[2]; /* dataset dimensions */
hsize_t curr_dims[RANK];
hsize_t maxdims[2];
hsize_t start[2];
hsize_t count[2];
herr_t status;
if (mode < 1)
{
if (H5Lexists(file, varname.c_str(), H5P_DEFAULT) > 0)
{
cout << "Dataset <" << varname
<< "> already exists. Please use a different variable name" << endl;
return 1;
}
}
/*
* Describe the size of the array and create the data space for fixed
* size dataset. RANK is Represents the dimension of the data space,
* i.e. the rank of the data space. In other words, RANK = the number
* of elements in `dimsf` below.
*/
if (mode < 1)
{
maxdims[0] = H5S_UNLIMITED;
maxdims[1] = U.size();
dimsf[0] = 1;
dimsf[1] = U.size();
dataspace = H5Screate_simple(RANK, dimsf, maxdims);
/*
* Define datatype for the data in the file.
* We will store little endian numbers.
*/
datatype = H5Tcopy(H5T_NATIVE_DOUBLE);
status = H5Tset_order(datatype, H5T_ORDER_LE);
assert(status == 0);
/* Modify dataset creation properties, i.e. enable chunking */
property = H5Pcreate(H5P_DATASET_CREATE);
hsize_t chunk_dims[2] = {1, U.size()};
status = H5Pset_chunk(property, RANK, chunk_dims);
/*
* Create a new dataset within the file using defined dataspace and
* datatype and dataset's chunk creation properties.
*/
dataset = H5Dcreate2(file, varname.c_str(), datatype, dataspace,
H5P_DEFAULT, property, H5P_DEFAULT);
/*
* Write the data to the dataset using default transfer properties.
*/
status = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, U.data());
assert(status == 0);
/*
* Close/release resources.
*/
H5Pclose(property);
H5Sclose(dataspace);
H5Tclose(datatype);
H5Dclose(dataset);
}
else
{
dataset = H5Dopen2(file, varname.c_str(), H5P_DEFAULT);
assert(dataset > 0); /* if Var exists*/
dataspace = H5Dget_space(dataset);
H5Sget_simple_extent_dims(dataspace, curr_dims, NULL);
assert(curr_dims[1] == U.size());
// cout << "curr_dims[0,1] = " << curr_dims[0] << "," << curr_dims[1] << endl; /* debug*/
num_slices = curr_dims[0];
curr_dims[0] = num_slices + 1; // Extend the dataset by one time slice
status = H5Dset_extent(dataset, curr_dims);
assert(status == 0);
dataspace = H5Dget_space(dataset);
H5Sget_simple_extent_dims(dataspace, curr_dims, NULL);
// cout << "curr_dims[0,1] = " << curr_dims[0] << "," << curr_dims[1] << endl; /* debug*/
start[0] = num_slices;
start[1] = 0;
count[0] = 1;
count[1] = U.size();
status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, NULL, count, NULL);
assert(status == 0);
memspace = H5Screate_simple(2, count, NULL);
status = H5Dwrite(dataset, H5T_NATIVE_DOUBLE, memspace, dataspace, H5P_DEFAULT, U.data());
assert(status == 0);
/*
* Close/release resources.
*/
H5Dclose(dataset);
H5Sclose(dataspace);
H5Sclose(memspace);
}
// H5Fclose(file); /* Should be closed outside this function*/
return 0;
}
int main(void)
{
hid_t file_id;
std::vector<double> U(10, 0.0);
int mode = 0;
std::string dfname = "a.h5";
if (mode == 0)
file_id = H5Fcreate(dfname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
else
file_id = H5Fopen(dfname.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
saveVec2HDF5_inside(file_id, U, std::string("U"), 0);
// saveVec2HDF5_inside(file_id, U, std::string("U"), 0);
saveVec2HDF5_inside(file_id, U, std::string("U"), 1);
H5Fclose(file_id);
return 0;
}