HDF5 简单读取数据集失败

Posted

技术标签:

【中文标题】HDF5 简单读取数据集失败【英文标题】:HDF5 Simple Read of Dataset Fails 【发布时间】:2019-03-04 15:23:02 【问题描述】:

我希望使用 C++ 从 hdf5 文件中进行简单读取。我将把它分成4个部分。 1st文件的样子。第二个我的代码试图读取文件。第三条错误信息。我的第四个结论。

1.文件-数据集可以在文件中找到,如图:

$ h5ls -r myfile.h5
/                     Group
/mydata               Dataset 1200

注意 - 数据集是一个包含 1200 个字符串的数组。请注意,CTYPE 是 H5T_C_S1,我将使用它来读取它。

HDF5 "myfile.h5" 
GROUP "/" 
   DATASET "mydata" 
      DATATYPE  H5T_STRING 
         STRSIZE H5T_VARIABLE;
         STRPAD H5T_STR_NULLTERM;
         CSET H5T_CSET_UTF8;
         CTYPE H5T_C_S1;
      
      DATASPACE  SIMPLE  ( 1200 ) / ( 1200 ) 
      DATA 
      (0): "pxsntpfcnkeesswwpwopksu", "exsytafcbkecsswwpwopnng",
      (2): "ebswtlfcbnecsswwpwopnnm", "pxywtpfcnneesswwpwopksu",
      (4): "exsgfnfwbktesswwpwoenag", "exyytafcbnecsswwpwopkng",

2.代码 - 我的代码尝试像这样读取数据集:

#include "H5Cpp.h"
#ifndef H5_NO_NAMESPACE
    using namespace H5;
#endif

const H5std_string FILE_NAME("myfile.h5");
const H5std_string DATASET_NAME("mydata");

// open file
H5File file(FILE_NAME, H5F_ACC_RDONLY);

// get dataset
DataSet dataset = file.openDataSet(DATASET_NAME);

// get src dataspace
DataSpace src = dataset.getSpace();

// get dimensions
int NUM_DIMS = src.getSimpleExtentNdims();
std::vector<hsize_t> dims(NUM_DIMS);
src.getSimpleExtentDims(&dims[0]);
hsize_t height = dims[0];
hsize_t width = 23;

// define src hyperslab
std::vector<hsize_t> count(NUM_DIMS, 1);
std::vector<hsize_t> offset(NUM_DIMS, 0);
src.selectHyperslab(H5S_SELECT_SET, &count[0], &offset[0]);

// define dst hyperslab
DataSpace dst(NUM_DIMS, dims);
dst.selectHyperslab(H5S_SELECT_SET, &count[0], &offset[0]);

// read data into memory, array of cstrings
std::vector<char*> data_out(height);
dataset.read(&data_out[0], H5T_C_S1, dst, src);

// print first line
std::cout << data_out[0] << std::endl;

3.错误 - 但是,它失败,原因似乎是 srcdst 超级实验室之间的类型不匹配,即使我设计了 srcdst具有相同的尺寸。错误信息如下:

HDF5-DIAG: Error detected in HDF5 (1.10.3) thread 0:
  #000: H5Dio.c line 199 in H5Dread(): can't read data
    major: Dataset
    minor: Read failed
  #001: H5Dio.c line 467 in H5D__read(): unable to set up type info
    major: Dataset
    minor: Unable to initialize object
  #002: H5Dio.c line 993 in H5D__typeinfo_init(): unable to convert between src and dest datatype
    major: Dataset
    minor: Feature is unsupported
  #003: H5T.c line 4546 in H5T_path_find(): can't find datatype conversion path
    major: Datatype
    minor: Can't get value
  #004: H5T.c line 4762 in H5T__path_find_real(): no appropriate function for conversion path
    major: Datatype
    minor: Unable to initialize object
HDF5-DIAG: Error detected in HDF5 (1.10.3) thread 0:
  #000: H5T.c line 1756 in H5Tclose(): immutable datatype
    major: Invalid arguments to routine
    minor: Bad value
DataType::~DataType - H5Tclose failed

4.我的结论 - 我尝试了许多变体,包括删除 dstsrc 作为 dataset.read() 的参数,将 H5T_C_S1 更改为 PredType::C_S1PredType::NATIVE_CHAR,但同样的错误仍然存​​在。

如何简单地将数据集读入内存?数据类型真的不匹配还是我没有定义其他东西?我还在读取函数中使用错误的数据类型吗?我是否不正确地定义了我的 hyperslab,以至于实际上存在类型不匹配?

【问题讨论】:

【参考方案1】:

也许您想尝试HDFql 并从 HDF5 低级细节中抽象出自己。在使用 HDFql 的 C++ 中,您可以像这样读取可变长度字符数据集 mydata(包含在文件 myfile.h5 中):

HDFql::execute("SELECT FROM myfile.h5 mydata"); // select (i.e. read) dataset "mydata" from file "myfile.h5" and populate default cursor with it

while(HDFql::cursorNext() == HDFql::Success) // display content of default cursor

    std::cout << HDFql::cursorGetChar() << std::endl;

【讨论】:

感谢您的建议。我会将其视为有用的抽象。

以上是关于HDF5 简单读取数据集失败的主要内容,如果未能解决你的问题,请参考以下文章

HDF5 C# pinvoke 读取数据集名称列表

如何使用 h5py 通过 szip 压缩访问 HDF5 数据集

为啥读取整个 hdf5 数据集比读取切片更快

使用 pandas 读取 hdf5 数据集

在 MATLAB 中读取 HDF5 数据集的一些特定元素

读取存储在 HDF5 中的部分数据集 - python 2.7