如何使用 C 从 hdf5 读取 H5T_STRING
How to read H5T_STRING from hdf5 using C
所以我有一个包含数据集的 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[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0",
(1) : "2015-05-13[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0",
(2) : "2015-05-14[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0",
(3) : "2015-05-15[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0",
(4) : "2015-05-16[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0"
}
我想使用 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);
尝试
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);
在深入研究 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;
或者,您可以在 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));
}
所以我有一个包含数据集的 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[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0",
(1) : "2015-05-13[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0",
(2) : "2015-05-14[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0",
(3) : "2015-05-15[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0",
(4) : "2015-05-16[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0[=11=]0"
}
我想使用 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);
尝试
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);
在深入研究 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;
或者,您可以在 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));
}