当前位置: 首页 > news >正文

HDF5文件 ——之三

H5GH5LH5OHDF5 C API 的分组接口,在 HDF.PInvoke.NETStandard(C# 的 HDF5 封装包)里,它们分别代表 HDF5 底层 对象层(Object layer)组层(Group layer)链接层(Link layer) 的操作模块。


🧱 一、背景概念

在 HDF5 中,一切数据(datasets、groups、attributes)都组织在一个层次结构里,像文件系统:

/                <-- 根组/GroupA/Dataset1/SubGroup/Dataset2

HDF5 的 API 是分模块设计的,C 层 API 对应多个模块,比如:

模块名 功能说明 常见函数前缀
H5F 文件(File)管理 H5F.create, H5F.open, H5F.close
H5G 组(Group)管理 H5G.create, H5G.open, H5G.get_info
H5D 数据集(Dataset)管理 H5D.create, H5D.write, H5D.read
H5S 数据空间(Dataspace)定义 H5S.create_simple
H5T 数据类型(Datatype)定义 H5T.copy, H5T.commit
H5A 属性(Attribute)操作 H5A.create, H5A.read
H5L 链接(Link)管理 H5L.create_hard, H5L.create_soft, H5L.exists
H5O 对象(Object)管理 H5O.open, H5O.get_info, H5O.copy

🧩 二、 H5GH5LH5O这三个模块

🧠 1. H5G —— Group(组)操作

代表 HDF5 层次结构中的“文件夹”。

常见用途:

  • 创建 / 打开 / 关闭组
  • 获取组信息(比如子对象数量)

常见函数:

long gid = H5G.create(fileId, "GroupA");
H5G.close(gid);

组是存放数据集和子组的容器。


🔗 2. H5L —— Link(链接)操作

HDF5 中的“链接”相当于文件系统里的“路径项”或“符号链接”。
每个对象(Group / Dataset)都通过“链接”挂在某个组下面。

主要作用:

  • 创建硬链接(hard link)或软链接(soft link)
  • 检查、移动、删除链接
  • 查询链接是否存在

常见函数:

H5L.create_hard(sourceLocId, "GroupA/Dataset1", destLocId, "CopiedDataset");
bool exists = H5L.exists(fileId, "GroupA/Dataset1") > 0;

区别:

  • 硬链接:多个路径指向同一个对象(类似 Linux 硬链接)
  • 软链接:路径字符串引用(类似符号链接)

🧩 3. H5O —— Object(对象)操作

HDF5 文件中所有可命名的东西(Group、Dataset、Datatype)都是 对象 (Object)
H5O 模块就是操作这些对象的通用接口。

主要用途:

  • 打开对象(不用区分是组还是数据集)
  • 获取对象信息(类型、创建时间、引用次数等)
  • 拷贝对象(整个数据集或组)
  • 检查对象是否存在

常见函数:

long oid = H5O.open(fileId, "GroupA/Dataset1");
H5O.info_t info = new H5O.info_t();
H5O.get_info(oid, ref info);
H5O.close(oid);

⚙️ 三、它们之间的关系

可以这么理解:

层次 模块 比喻(文件系统类比)
文件 H5F 打开/关闭文件
H5G 文件夹操作
链接 H5L 文件系统中的路径项 / 软硬链接
对象 H5O 一切可被命名的对象(文件或文件夹)

它们是互相关联的:

  • H5G 管理组本身
  • H5L 管理路径和命名
  • H5O 管理底层对象元信息

🧪 四、举个例子

比如我们想复制一个数据集:

// 等价于 shell 命令: cp /GroupA/Dataset1 /GroupB/DatasetCopy
H5O.copy(fileId, "/GroupA/Dataset1", fileId, "/GroupB/DatasetCopy", 0, 0);

内部其实涉及:

  • H5L 查找 /GroupA/Dataset1 这个路径对应的链接;
  • H5O 拿到实际对象;
  • H5G 用于定位组 /GroupB

✅ 小结

模块 作用 常用函数
H5G 操作组(Group) create, open, get_info, close
H5L 操作链接(路径、软硬链接) create_hard, create_soft, exists, delete
H5O 操作通用对象(Group / Dataset / Type) open, get_info, copy, close

下面是一个 完整的示例 C# 程序
HDF.PInvoke 创建一个文件 → 新建组 /GroupA → 在里面新建一个数据集 → 用 H5O.copy 复制它 → 用 H5L.exists 验证链接存在。

非常好 👍
下面是一个完整的、可以直接运行的 C# 示例程序,使用 NuGet 包
HDF.PInvoke.NETStandard (v1.10.502)

它演示了:

  • 创建 HDF5 文件
  • 创建组(H5G
  • 创建数据集(H5D
  • 复制对象(H5O.copy
  • 检查链接是否存在(H5L.exists
  • 最后关闭所有资源

并附带详细中文注释,帮助我们理解 HDF5 各层的作用。


✅ 完整代码示例(可运行)

using System;
using HDF.PInvoke;
using System.Runtime.InteropServices;class Program
{static void Main(){const string fileName = "example.h5";//=====================================================// 一、创建一个新的 HDF5 文件//=====================================================// H5F_ACC_TRUNC 表示如果文件存在则覆盖long fileId = H5F.create(fileName, H5F.ACC_TRUNC);Console.WriteLine($"✅ 创建文件: {fileName}, fileId = {fileId}");//=====================================================// 二、在根目录下创建一个组 /GroupA//=====================================================long groupId = H5G.create(fileId, "/GroupA");Console.WriteLine("✅ 创建组: /GroupA");//=====================================================// 三、在 /GroupA 下创建一个简单的数据集 /GroupA/Dataset1//=====================================================// 定义一个简单的 1D 空间,长度为 5ulong[] dims = { 5 };long spaceId = H5S.create_simple(1, dims, null);// 数据类型:float (32位)long typeId = H5T.copy(H5T.NATIVE_FLOAT);// 创建数据集long datasetId = H5D.create(groupId, "Dataset1", typeId, spaceId);Console.WriteLine("✅ 创建数据集: /GroupA/Dataset1");// 写入一些测试数据float[] data = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f };GCHandle hnd = GCHandle.Alloc(data, GCHandleType.Pinned);H5D.write(datasetId, H5T.NATIVE_FLOAT, H5S.ALL, H5S.ALL, H5P.DEFAULT, hnd.AddrOfPinnedObject());hnd.Free();Console.WriteLine("✅ 写入数据完成");// 关闭数据集和空间H5D.close(datasetId);H5S.close(spaceId);H5T.close(typeId);H5G.close(groupId);//=====================================================// 四、创建另一个组 /GroupB//=====================================================long groupBId = H5G.create(fileId, "/GroupB");H5G.close(groupBId);Console.WriteLine("✅ 创建组: /GroupB");//=====================================================// 五、使用 H5O.copy() 将 Dataset1 从 GroupA 复制到 GroupB//=====================================================// 语法: H5O.copy(src_loc, src_name, dst_loc, dst_name, cpypl_id, lcpl_id)// 参数解释://   src_loc: 源所在的文件或组 ID//   src_name: 源路径//   dst_loc: 目标文件或组 ID//   dst_name: 新对象路径//   cpypl_id: 拷贝属性列表(默认 0)//   lcpl_id: 链接创建属性列表(默认 0)H5O.copy(fileId, "/GroupA/Dataset1", fileId, "/GroupB/DatasetCopy", 0, 0);Console.WriteLine("✅ 复制对象: /GroupA/Dataset1 → /GroupB/DatasetCopy");//=====================================================// 六、使用 H5L.exists() 检查新链接是否存在//=====================================================bool exists = H5L.exists(fileId, "/GroupB/DatasetCopy") > 0;Console.WriteLine($"🔍 链接 /GroupB/DatasetCopy 是否存在: {exists}");//=====================================================// 七、用 H5O.open() 打开复制后的对象,并读取信息//=====================================================long objId = H5O.open(fileId, "/GroupB/DatasetCopy");H5O.info_t info = new H5O.info_t();H5O.get_info(objId, ref info);Console.WriteLine($"ℹ️ 对象类型: {info.type}"); // H5O.type_t.DATASETH5O.close(objId);//=====================================================// 八、关闭文件//=====================================================H5F.close(fileId);Console.WriteLine("✅ 文件已关闭");}
}

🧭 运行后输出示例

✅ 创建文件: example.h5, fileId = 72057594037927936
✅ 创建组: /GroupA
✅ 创建数据集: /GroupA/Dataset1
✅ 写入数据完成
✅ 创建组: /GroupB
✅ 复制对象: /GroupA/Dataset1 → /GroupB/DatasetCopy
🔍 链接 /GroupB/DatasetCopy 是否存在: True
ℹ️ 对象类型: H5O_TYPE_DATASET
✅ 文件已关闭

运行结束后,得到一个结构如下的 HDF5 文件:

/
├── GroupA
│   └── Dataset1
└── GroupB└── DatasetCopy

💡 总结要点

模块 功能 示例
H5G 操作组(Group) 创建 /GroupA, /GroupB
H5D 操作数据集(Dataset) 创建并写入 Dataset1
H5O 操作对象(Object) 复制整个对象,查询信息
H5L 操作链接(Link) 检查路径是否存在

http://www.hskmm.com/?act=detail&tid=24411

相关文章:

  • 代码随想录算法训练营|Day 25
  • 深入解析:SAE J3072-2024插电式电动汽车(PEV)中的车载逆变器系统安全标准介绍
  • 冷僻模板整理
  • 实用指南:gitlab-runner 再次实践中理解和学习
  • 2025年7月28日当周关键漏洞汇总分析
  • C# 与 C/C++ 互操作
  • 【自然语言处理】文本规范化知识点梳理与习题总结 - 教程
  • 邮票收集问题正推证明
  • 2025多校冲刺CSP模拟赛2 2025.10.4 模拟炸
  • 算法乱谈
  • 2025 年 9 月习题集
  • C# 代码规范
  • 实用指南:babelfish for postgresql 分析--todo
  • NFC 贴卡自动拨打微信视频电话
  • 10.4
  • 实用指南:d-分离:图模型中的条件独立性判定准则
  • [MCP] 监听资源更新
  • [RAG] 基础知识
  • CF1408F Two Different
  • 数据结构 - 字典树 Trie
  • 激活函数实现
  • 漏洞赏金入门指南:从零开始的实战方法论
  • PMON failed to acquire latch 的报错及sqlplus / as sysdba 无法连接 - 详解
  • 2025CSP-S模拟赛58 比赛总结
  • 精读C++设计模式20 —— 结构型设计模式:桥接模式 - 详解
  • 用纯.NET开发并制作一个智能桌面机器人(六):使用.NET开发一个跨平台功能完善的小智AI客户端
  • 2025/10/4 总结
  • Qt处理Windows平板上摄像头
  • 你必须知道的TCP和UDP核心区别,快速搞懂这两大协议!
  • [swift 外部干涉法 extension]