• golang_操作HDF5文件_gonum/hdf5_linux_libhdf5dev_遍历文件结构


    golang_操作HDF5文件_gonum/hdf5_linux_libhdf5-dev_遍历文件结构

    转载注明来源: 本文链接 来自osnosn的博客,写于 2022-01-22.

    参考

    笔记

    • Debian-11 需要 apt install libhdf5-dev (安装成功。是 hdf5-1.10.6)
    • CentOS-8 需要 yum install hdf5-devel (需要epel)
      • 如果提示:安装失败,包冲突。启用 yum config-manager --enable powertools,就可以安装了。
        版本较低, 是 hdf5-1.10.5
    • 另一个选择,去下载源码包 然后
      ./configure --prefix=/usr/local/hdf5
      make
      make check
      make install
      通过源码安装。可以安装最新的。
    • 参考 【gonum/hdf5/cmd】中的例子。

    遍历hdf5结构 (不能遍历属性)

    //filename: read_hdf5.go
    
    package main
    
    import (
            "flag"
            "fmt"
            "gonum.org/v1/hdf5"
    )
    
    func main() {
            hdf5_filename := "" //命令行参数,hdf5文件名
            flag.StringVar(&hdf5_filename, "f", "", "hdf5 filename")
            flag.Parse()
    
            if len(hdf5_filename) < 2 {
                    fmt.Printf("hdf5 file missing!\n")
                    return
            }
    
            fmt.Println()
            //版本号
            version, err := hdf5.LibVersion()
            if err != nil {
                    fmt.Printf("** error ** %s\n", err)
                    return
            }
            fmt.Printf("=== version: %s ===\n", version)
            // check hdf5 file
            if !hdf5.IsHDF5(hdf5_filename) {
                    fmt.Printf("\"%s\" Not a hdf5 file!\n", hdf5_filename)
                    return
            }
            // open hdf5 file
            ff, err := hdf5.OpenFile(hdf5_filename, hdf5.F_ACC_RDONLY)
            if err != nil {
                    panic(err)
            }
            fmt.Printf("=== hdf5 opened.\n")
    
            //显示hdf5 结构, 仅支持 group,dataset 两种
            prefix := " " //至少一个空格
            Show_h5(prefix, &ff.CommonFG)
    
            fmt.Printf("=== close hdf5.\n")
            ff.Close()
    }
    
    func Show_h5(prefix string, obj *hdf5.CommonFG) {
            //显示当前节点的 名称,类型
            fmt.Printf("%s(%s) %s \n", prefix, obj.Type(), obj.Name())
            //获取当前节点中包含的,下级节点数目
            ObjNum, _ := obj.NumObjects()
            if ObjNum < 1 {
                    return
            }
            prefix = prefix[:len(prefix)-1] + " |-" //前缀,缩进一层
            for ii := uint(0); ii < ObjNum; ii++ {
                    ObjName, _ := obj.ObjectNameByIndex(ii) //节点name
                    ObjType, _ := obj.ObjectTypeByIndex(ii) //节点type
                    if ObjType == hdf5.H5G_GROUP { //是GROUP
                       //fmt.Printf("%s(%s) %s \n", prefix, ObjType, ObjName)
                            obj, _ := obj.OpenGroup(ObjName)
                            Show_h5(prefix, &obj.CommonFG) //递归调用
                            obj.Close()
                    } else if ObjType == hdf5.H5G_DATASET { //是DATASET
                       fmt.Printf("%s(%s) %s \n", prefix, ObjType, ObjName)
                    }
            }
    
    }
    
    • 编译,执行
      go build read_hdf5.go
      ./read_hdf5 -f xxxx.hdf5
    • 无法遍历 属性
      • hdf5 group 官网
        • Documentation->HDF5->HDF5 Examples ->【Examples in the Source Code】的例子 【h5_attribute.c】 中,给出了在 C++ 中遍历属性的方法。用到了H5Oget_info3()H5Aiterate2()
        • Documentation->HDF5->HDF5 User Guides->HDF5 User's Guide也写了。
      • 可是 gonum/hdf5 并没有封装这两个函数(2022-01)。
    • 属性,无法获取它的 Datatype,应该是没封装这个功能(2022-01)。

    读取hdf5的dataset中的属性

    // 或者 obj = & hdf5_fd.CommonFG  // hdf5_fd = hdf5.OpenFile( ... )
    // 或者 obj = & group.CommonFG    // group = xxx.OpenGroup( ... )
    
     dset, _ := obj.OpenDataset("mydataset")
     attName := "Description"  //字符串类型的属性
     att, err := dset.OpenAttribute(attName)
     if err == nil {
        var buf string
        att.Read(&buf, hdf5.T_GO_STRING)
        buflen := len(buf)
        fmt.Printf(" %s=%s (%d)\n", attName,  buf, buflen)
        att.Close()
     }
     attName = "Rate"        //float32 类型的属性
     att, err = dset.OpenAttribute(attName)
     if err == nil {
        var rate float32
        att.Read(&rate, hdf5.T_NATIVE_FLOAT)
        fmt.Printf(" %s=%.3f \n", attName,  rate)
        att.Close()
     }
     dset.Close()
    
    • 属性,无法获取它的 Datatype,应该是没封装这个功能(2022-01)。
    • 指定 float32 属性的读取,没问题。
    • 指定 string 属性的读取。有的读取正常,有的会多读出几个字节的乱码。我也无法解决。估计是 gonum/hdf5 封装的问题。
      用系统自带的hdf5-tools(C写的工具),读取string的属性,很正常。
      • 系统debian-11, 装的是hdf5-1.10.6 , gonum/hdf5 是最新的包(2022-01)。
    • 无法获取单条记录的总大小,itemsize。(2022-01)
    • 读取数据可以用 []byte 做 buffer,用 encoding/binary 包,LittleEndian 解析。
    • 总之,gonum/hdf5 远未完成。没法使用。(2022-01)

    静态编译

    • CGO_ENABLED=1 go build -v -ldflags '-w -s -extldflags "-static -lhdf5 -lhdf5_hl -lhdf5_serial -lhdf5_serial_hl -lm -ldl -lz -lsz -laec"' xxx.go
      会有个warning,说 hdf5 用了 dl 库的 dlopen,会在运行中加载 glibc 动态库。
      所以,静态编译的程序,需要在有相同 glibc 的系统中。
      • 我测试,debian中编译的,在centos中运行会有问题,只要操作hdf5文件,就会出错退出
        但可以在别的,没装hdf5库的debian中运行,操作hdf5文件。

    转载注明来源: 本文链接 https://www.cnblogs.com/osnosn/p/15834309.html
    来自 osnosn的博客 https://www.cnblogs.com/osnosn/ .


  • 相关阅读:
    HDU 1358 Period (KMP)
    POJ 1042 Gone Fishing
    Csharp,Javascript 获取显示器的大小的几种方式
    css text 自动换行的实现方法 Internet Explorer,Firefox,Opera,Safar
    Dynamic Fonts动态设置字体大小存入Cookie
    CSS Image Rollovers翻转效果Image Sprites图片精灵
    CSS three column layout
    css 自定义字体 Internet Explorer,Firefox,Opera,Safari
    颜色选择器 Color Picker,Internet Explorer,Firefox,Opera,Safar
    CSS TextShadow in Safari, Opera, Firefox and more
  • 原文地址:https://www.cnblogs.com/osnosn/p/15834309.html
Copyright © 2020-2023  润新知