【问题标题】:How to read H5T_STRING from hdf5 using C如何使用 C 从 hdf5 读取 H5T_STRING
【发布时间】:2019-03-28 18:56:35
【问题描述】:

所以我有一个包含数据集的 hdf5 文件:

DATASET "updateDateTime" {DATATYPE  H5T_STRING{
    STRSIZE 24;
STRPAD H5T_STR_NULLPAD;
CSET H5T_CSET_ASCII;
CTYPE H5T_C_S1;
}
    DATASPACE  SIMPLE{ (5) / (5) }
    DATA{
    (0) : "2015-05-12\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
    (1) : "2015-05-13\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
    (2) : "2015-05-14\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
    (3) : "2015-05-15\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
    (4) : "2015-05-16\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
}

我想用 C 来读取这个数据集,但是我找不到合适的例子(我是 HDF5 的新手)。具体来说,我无法确定在阅读时使用哪个 H5T_NATIVE_*。这是我现在拥有的代码:

hid_t  time_ds = H5Dopen(grp, "updateDateTime", H5P_DEFAULT);
auto time_shape = get_dataset_shape(time_ds);
char** time_str = (char **)malloc(time_shape[0] * sizeof(char *)); // TODO: memeory allocation correct??

 status = H5Dread(time_ds, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT,
    time_str);
 /*do my stuff*/

free(time_str);
status = H5Dclose(time_ds);

【问题讨论】:

  • 当你执行这段代码时会发生什么?
  • 嗯,time_str 在 H5Dread() @arboreal84 之后没有填充数据

标签: hdf5


【解决方案1】:

试试

char* time_str = (char*) malloc(time_shape[0] * sizeof(char));

status = H5Dread(time_ds, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, &time_str);

【讨论】:

  • 谢谢,但这似乎不起作用。 time_str 还是空的
【解决方案2】:

在深入研究了h5dump的源代码(该工具附带hdf5包)后,我终于让它工作了。我不能说这是一个好的解决方案,但希望这可以帮助遇到类似问题的其他人。

原来这个函数可以推测出原生类型

hid_t h5tools_get_native_type(hid_t type)
{
hid_t p_type;
H5T_class_t type_class;

type_class = H5Tget_class(type);
if (type_class == H5T_BITFIELD)
    p_type = H5Tcopy(type);
else
    p_type = H5Tget_native_type(type, H5T_DIR_DEFAULT);

return(p_type);
}

然后,像这样读取数据集:

type = H5Dget_type(dset);
native_type = h5tools_get_native_type(type);
auto shape = get_dataset_shape(dset);
n_element = std::accumulate(shape.begin(), shape.end(), 1ull, std::multiplies<size_t>());
type_size = std::max(H5Tget_size(type), H5Tget_size(native_type));
size_t alloc_size = n_element * type_size;
char * buf = BAT_NEW char[alloc_size]; 

status = H5Dread(dset, native_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);

/*do my stuff*/

H5Tclose(native_type);
H5Tclose(type);
delete[] buf;

【讨论】:

    【解决方案3】:

    或者,您可以像这样在 C 中使用 HDFql 读取数据集(数据类型为 H5T_STRING):

    hdfql_execute("SELECT FROM updateDateTime");
    hdfql_cursor_first(NULL);
    printf("Dataset value is %s\n", hdfql_cursor_get_char(NULL));
    

    如果数据集存储了多个字符串(通过查看上面发布的 h5dump 的结果似乎是您的情况),您可以通过循环结果集来检索这些:

    hdfql_execute("SELECT FROM updateDateTime");
    while(hdfql_cursor_next(NULL) == HDFQL_SUCCESS)
    {
       printf("Dataset value is %s\n", hdfql_cursor_get_char(NULL));
    }
    

    【讨论】:

      猜你喜欢
      • 2021-02-24
      • 2018-04-08
      • 2013-08-06
      • 2014-06-01
      • 2012-11-28
      • 2014-04-06
      • 2019-06-24
      • 2021-12-09
      • 2016-06-18
      相关资源
      最近更新 更多