我有一個包含以下內容的 HDF5 檔案:
$ h5dump foo.h5
HDF5 "foo.h5" {
GROUP "/" {
ATTRIBUTE "Version" {
DATATYPE H5T_STRING {
STRSIZE 5;
STRPAD H5T_STR_NULLTERM;
CSET H5T_CSET_ASCII;
CTYPE H5T_C_S1;
}
DATASPACE SIMPLE { ( 1 ) / ( 1 ) }
DATA {
(0): "1.2.0"
}
}
...
如何STRSIZE從屬性中提取(在本例中為 5)?我目前可以通過分配比我認為需要的更多的記憶體來提取整個字串:
char version_string[] = "hello_hello_hello";
hid_t attr = H5Aopen(file_id, "Version", H5P_DEFAULT);
hid_t atype = H5Tcopy(H5T_C_S1);
H5Tset_size(atype, 17);
herr_t err = H5Aread(attr, atype, version_string);
H5Aclose(attr);
H5Tclose(atype);
但是,我想不出如何找到分配權有關的記憶的字串。
uj5u.com熱心網友回復:
(免責宣告:我不是 HDF5 用戶)
通過查看檔案,我認為您需要使用H5Aget_storage_size 來確定要與H5Aread.
hid_t versionAttr = H5Aopen( file_id, "Version", H5P_DEFAULT );
if( versionAttr < 0 ) goto cleanup1;
size_t versionAttrSize = 0;
{
hsize_t size = H5Aget_storage_size( versionAttr );
if( size == 0 ) {
// get_storage_size failed for some reason but the documentation isn't helpful. Grrrr.
// TODO: Show an error message here, I guess.
goto cleanup2;
}
else if( size > SIZE_MAX ) {
// The data on-disk is larger than can be represented in C on your platform.
// TODO: Show an error message here, I guess.
goto cleanup2;
}
else {
versionAttrSize = (size_t)size;
}
}
char* versionAttrBuffer = malloc( versionAttrSize );
if( !versionAttrBuffer ) {
// Computer broken.
goto cleanup2;
}
herr_t versionAttrBufferReadError = H5Aread( versionAttr, H5T_C_S1, versionAttrBuffer );
if( versionAttrBufferReadError < 0 ) {
goto cleanup3;
}
// Do stuff with `versionAttrBuffer` here.
printf( "String attribute length: %d\n", versionAttrSize );
printf( "String attribute data: \"%s\"", versionAttrBuffer );
cleanup3:
free( versionAttrBuffer );
cleanup2:
herr_t cleanupErr = H5Aclose( versionAttr );
if( cleanupErr < 0 ) { die( "This should never happen." ); };
cleanup1:
// TODO: Close file?
uj5u.com熱心網友回復:
使在 C 中處理 HDF5 檔案更容易的另一種方法是使用HDFql。要分配適量的記憶體來存盤固定長度字串的屬性值,可以按如下方式完成(在 C 中使用 HDFql):
long long size;
char *data;
hdfql_variable_transient_register(&size);
hdfql_execute("SHOW SIZE foo.h5 \"Version\" INTO MEMORY 0");
printf("String size: %lld\n", size);
data = malloc(size);
hdfql_variable_transient_register(&data);
hdfql_execute("SELECT FROM foo.h5 \"Version\" INTO MEMORY 0");
printf("String data: %s\n", data);
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/357604.html
