HDF5文件中数据属性的读写操作示例

HDF5属性(attribute)是附加到数据集(dataset)或组(group)上的元数据,用于描述数据的特性。下面分别展示C++、Fortran和Python中如何读写HDF5属性。

1. C++ 示例

#include <iostream>
#include <H5Cpp.h>

using namespace H5;

void write_attribute() {
    // 创建新文件
    H5File file("example.h5", H5F_ACC_TRUNC);
    
    // 创建数据集
    hsize_t dims[2] = {3, 3};
    DataSpace dataspace(2, dims);
    DataSet dataset = file.createDataSet("dataset", PredType::NATIVE_INT, dataspace);
    
    // 写入属性
    Attribute attr = dataset.createAttribute("units", PredType::C_S1, DataSpace(H5S_SCALAR));
    const char* unit_str = "meters";
    attr.write(PredType::C_S1, unit_str);
    
    // 写入另一个数值属性
    int version = 2;
    Attribute attr2 = dataset.createAttribute("version", PredType::NATIVE_INT, DataSpace(H5S_SCALAR));
    attr2.write(PredType::NATIVE_INT, &version);
}

void read_attribute() {
    // 打开文件
    H5File file("example.h5", H5F_ACC_RDONLY);
    DataSet dataset = file.openDataSet("dataset");
    
    // 读取字符串属性
    Attribute attr = dataset.openAttribute("units");
    char unit_str[10];
    attr.read(PredType::C_S1, unit_str);
    std::cout << "Units: " << unit_str << std::endl;
    
    // 读取数值属性
    Attribute attr2 = dataset.openAttribute("version");
    int version;
    attr2.read(PredType::NATIVE_INT, &version);
    std::cout << "Version: " << version << std::endl;
}

int main() {
    write_attribute();
    read_attribute();
    return 0;
}

2. Fortran 示例

program hdf5_attribute_example
    use hdf5
    implicit none
    
    integer :: hdferr
    integer(HID_T) :: file_id, dset_id, attr_id, space_id
    integer(HSIZE_T), dimension(1) :: dims = (/1/)
    character(len=20) :: attr_string = "meters"
    integer :: attr_integer = 2, read_integer
    character(len=20) :: read_string
    
    ! 初始化HDF5接口
    call h5open_f(hdferr)
    
    ! 创建新文件
    call h5fcreate_f("example.h5", H5F_ACC_TRUNC_F, file_id, hdferr)
    
    ! 创建数据集
    dims = (/3, 3/)
    call h5screate_simple_f(2, dims, space_id, hdferr)
    call h5dcreate_f(file_id, "dataset", H5T_NATIVE_INTEGER, space_id, dset_id, hdferr)
    call h5sclose_f(space_id, hdferr)
    
    ! 写入字符串属性
    call h5screate_f(H5S_SCALAR_F, space_id, hdferr)
    call h5acreate_f(dset_id, "units", H5T_C_S1, space_id, attr_id, hdferr)
    call h5awrite_f(attr_id, H5T_C_S1, attr_string, dims, hdferr)
    call h5aclose_f(attr_id, hdferr)
    call h5sclose_f(space_id, hdferr)
    
    ! 写入整数属性
    call h5screate_f(H5S_SCALAR_F, space_id, hdferr)
    call h5acreate_f(dset_id, "version", H5T_NATIVE_INTEGER, space_id, attr_id, hdferr)
    call h5awrite_f(attr_id, H5T_NATIVE_INTEGER, attr_integer, dims, hdferr)
    call h5aclose_f(attr_id, hdferr)
    call h5sclose_f(space_id, hdferr)
    
    ! 关闭数据集和文件
    call h5dclose_f(dset_id, hdferr)
    call h5fclose_f(file_id, hdferr)
    
    ! 重新打开文件读取属性
    call h5fopen_f("example.h5", H5F_ACC_RDONLY_F, file_id, hdferr)
    call h5dopen_f(file_id, "dataset", dset_id, hdferr)
    
    ! 读取字符串属性
    call h5aopen_f(dset_id, "units", attr_id, hdferr)
    call h5aread_f(attr_id, H5T_C_S1, read_string, dims, hdferr)
    print *, "Units: ", trim(read_string)
    call h5aclose_f(attr_id, hdferr)
    
    ! 读取整数属性
    call h5aopen_f(dset_id, "version", attr_id, hdferr)
    call h5aread_f(attr_id, H5T_NATIVE_INTEGER, read_integer, dims, hdferr)
    print *, "Version: ", read_integer
    call h5aclose_f(attr_id, hdferr)
    
    ! 关闭所有资源
    call h5dclose_f(dset_id, hdferr)
    call h5fclose_f(file_id, hdferr)
    call h5close_f(hdferr)
    
end program hdf5_attribute_example

3. Python 示例 (使用h5py)

import h5py
import numpy as np

def write_attribute():
    # 创建新文件
    with h5py.File('example.h5', 'w') as f:
        # 创建数据集
        dataset = f.create_dataset("dataset", (3, 3), dtype='i4')
        
        # 写入字符串属性
        dataset.attrs['units'] = 'meters'
        
        # 写入数值属性
        dataset.attrs['version'] = 2
        
        # 写入数组属性
        dataset.attrs['temperature_range'] = np.array([-10.0, 40.0])

def read_attribute():
    # 打开文件
    with h5py.File('example.h5', 'r') as f:
        dataset = f['dataset']
        
        # 读取字符串属性
        print("Units:", dataset.attrs['units'])
        
        # 读取数值属性
        print("Version:", dataset.attrs['version'])
        
        # 读取数组属性
        print("Temperature range:", dataset.attrs['temperature_range'][...])
        
        # 遍历所有属性
        print("\nAll attributes:")
        for name in dataset.attrs:
            print(f"{name}: {dataset.attrs[name]}")

if __name__ == "__main__":
    write_attribute()
    read_attribute()

注意事项

  1. 在C++和Fortran中,需要确保正确管理HDF5对象的生命周期,及时关闭打开的对象。
  2. Python的h5py库提供了更简洁的API,是处理HDF5文件的推荐方式。
  3. 属性可以附加到数据集或组上,用于存储元数据。
  4. 属性可以是标量、一维数组或字符串等不同类型。
  5. 在编写生产代码时,应添加适当的错误处理。

以上示例展示了HDF5属性的基本读写操作,您可以根据实际需求进行扩展。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐