我如何使用GO语言读取可能是两种不同数据类型之一的HDF5属性

How do I read an HDF5 attribute which could be one of two different data types, using the GO language?

本文关键字:数据类型 属性 HDF5 两种 GO 何使用 语言 读取      更新时间:2023-10-16

我正在移植现有的C 应用程序,以作为评估项目的一部分。作为其中的一部分,我需要读取两个数据集属性,在某些文件中,这些属性被存储为double,在某些文件中作为浮点部存储。我用来处理此操作的C 代码如下(我们在Debian Linux上使用Libhdf5-CPP-100)。

const auto att = dataSet.openAttribute(attributeName);
if (att.getDataType() == H5::PredType::NATIVE_DOUBLE) {
    att.read(att.getDataType(), &attributeValue);
}
else if (att.getDataType() == H5::PredType::NATIVE_FLOAT) {
    float temp = 0.F;
    att.read(att.getDataType(), &temp);
    attributeValue = static_cast<double>(temp);
}
else {
    // we throw an exception indicating we don't support the type
}

我的问题是,我很难在GO中写下同等的内容。(我正在使用" gonum.org/v1/hdf5"软件包。)读取方法似乎很简单:

func (s *Attribute) Read(data interface{}, dtype *Datatype) error

,但我正在努力确定将其传递为数据类型,因为属性类型似乎没有GetDataType方法。我看到的最接近:

func (s *Attribute) GetType() Identifier

但这不会返回数据类型,而是返回标识符。我尝试了以下比较,即给定标识符我可以确定数据类型的假设:

if attr.GetType().ID() == hdf5.T_NATIVE_DOUBLE.ID() {
    // handle as a double
}

但这无效。从getType()返回的ID与double或float的ID不同。

我曾在https://godoc.org/gonum.org/v1/hdf5上通过在线文档,但无法找到解决我问题的解决方案。(或使用GO读取HDF5属性的任何示例。)

有人设法做这样的事情吗?还是大多数示例只是假设类型而不是查询它?

我已经确认了我的怀疑,现在有了适当的答案。必不可少的问题是,我使用C API存在错误(在某些情况下只会导致双倍写1/2),而我实际上是在尝试重复GO中的错误。实际上,解决方案非常简单。

传递到属性read方法中的属性类型不是属性的类型,而是您想要将其转换为存储在内存中的类型。这意味着我的C 代码应该更简单,因为无需检查属性类型,也不需要static_cast。要读取和存储属性值,请依靠HDF5执行转换,如果属性无法转换为双重,则可以抛出适当的例外,就像

一样简单
const auto att = dataSet.openAttribute("my attribute name");
att.read(H5::PredType::NATIVE_DOUBLE, &attributeValue);

GO版本更多地工作,因为我们必须手动管理对象生命周期和错误条件,但是在这里。(请注意,我假设" ...处理错误..."也涉及提前出口,否则需要额外的话来检查ATT不是零。)

att, err := dataSet.OpenAttribute("my attribute name")
if err != nil {
    ...handle the error...
}
err = att.Read(&attributeValue, hdf5.T_NATIVE_DOUBLE)
if err != nil {
    ...handle the error...
}
err = att.Close()
if err != nil {
    ...handle the error...
}