(C++) 在 HDF5 中编写数据库

Posted

技术标签:

【中文标题】(C++) 在 HDF5 中编写数据库【英文标题】:(C++) Writing a database in HDF5 【发布时间】:2018-08-25 19:54:51 【问题描述】:

您好,这是我第一次使用 HDF5,我正在尝试使用手动创建的数据集创建数据库表。文件已创建并已部署,但是每次我尝试插入单个数据注册表(每次 cv::mat 为 1x6,因为我尝试插入整个数据集但我也无法插入)我收到以下消息:

H5Dwrite(): 文件选择+偏移不在范围内 专业:数据空间 次要:超出范围 在抛出 'H5::DataSetIException' 的实例后调用终止

我使用的代码如下

cv::Mat label;
int size = data.length()/n_features_objects;

size_t size_[2]=1,(hsize_t)n_features_objects;
hsize_t chunk[2]=1,(hsize_t)n_features_objects;
hsize_t max_size[2]=H5S_UNLIMITED,(hsize_t)n_features_objects;
H5::DSetCreatPropList prop;
prop.setChunk(2,chunk);
H5::DataSpace ds(2, size_,max_size);
H5::IntType datatype =  H5::PredType::NATIVE_UINT64;
objects = labelFile.createDataSet(objects_name.toStdString(),datatype, ds,prop);

//get size of the dataset
H5::DataSpace ds = objects.getSpace();
int dims = ds.getSimpleExtentNdims();
hsize_t rc [dims];
ds.getSimpleExtentDims(rc);
int rows = (int)rc[0];

for(int z=0; z<size;z++)

    hsize_t new_size[2]=1, (hsize_t)n_features_objects;
    labels.extend(new_size);

    cv::Mat label_oreg = cv::Mat::zeros(cv::Size(n_features_objects,1), CV_32SC1);
    //Adding data registries one by one
    label_oreg.at<int>(0,0) = label_oreg.at<int>(z,0);
    label_oreg.at<int>(0,1) = label_oreg.at<int>(z,1);
    label_oreg.at<int>(0,2) = label_oreg.at<int>(z,2);
    label_oreg.at<int>(0,3) = label_oreg.at<int>(z,3);
    label_oreg.at<int>(0,4) = label_oreg.at<int>(z,4);
    label_oreg.at<int>(0,5) = label_oreg.at<int>(z,5);

    hsize_t rows_ext[2] =1, (hsize_t)n_features_objects;
    hsize_t offset[2] =(hsize_t)1, 0;
    ds = labels.getSpace();
    ds.selectHyperslab(H5S_SELECT_SET,rows_ext, offset);
    H5::DataSpace mem_space(2, rows_ext);
    labels.write(label.data, H5::PredType::NATIVE_INT32, mem_space, ds);

有人知道我在这里缺少什么吗?我认为我的结果很奇怪,因为我总是在数据空间中注册了一个新的数据块,以便将其用作放置注册表。

【问题讨论】:

【参考方案1】:

根据您的问题的标题和描述,您似乎希望在不覆盖现有数据的情况下将数据添加(即追加)到 HDF5 数据集中,就像表(在关系数据库中)允许您添加行而不覆盖现有行。

如果这是正确的,这里有一个通用示例来说明如何在 C++ 中使用 HDFql 来完成(我不知道如何在其他 HDF5 C++ API 中做到这一点):

// declare variable
unsigned long long values[6];

// create HDF5 file "my_file.h5" and use (i.e. open) it
HDFql::execute("CREATE AND USE FILE my_file.h5");

// create HDF5 dataset "my_dataset" of datatype unsigned long long (64 bit) of two dimensions (unlimited x 6)
HDFql::execute("CREATE CHUNKED(1, 6) DATASET my_dataset AS UNSIGNED BIGINT(0 TO UNLIMITED, 6)");

// register variable "values" for subsequent use (by HDFql)
HDFql::variableRegister(values);

// keep reading data (from hypothetical function "read") and store it in variable "values" until there is no more to read
while(read(values))

    // extend first dimension of dataset "my_dataset" one unit
    HDFql::execute("ALTER DIMENSION my_dataset TO +1");

    // insert (i.e. write) content of variable "values" into the last position of the first dimension of dataset "my_dataset" (thanks to a hyperslab selection)
    HDFql::execute("INSERT INTO my_dataset(-1:1:1:1) VALUES FROM MEMORY 0");


// unregister variable "values" as it is no longer used/needed (by HDFql)
HDFql::variableUnregister(values);

【讨论】:

感谢@SOG 提供的示例。你是对的,但是这是我正在从现有的代码修改的代码。

以上是关于(C++) 在 HDF5 中编写数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何在现有 HDF5 文件上创建组? (HDF5)

如何从 C++ 中的 hdf5 文件中读取数据块?

将浮点数组写入和附加到 C++ 中 hdf5 文件中的唯一数据集

如何在 HDF5 中编写固定长度的字符串?

HDF5 用于使用 fortran 编写的数据文件

如何使用 C++ 库在 HDF5 中找出数据集的 PredType