HDF5文件格式:数据类型与读写功能详解
HDF5简介
HDF5(Hierarchical Data Format version 5)是一种用于存储和管理大量科学数据的文件格式和库。它由美国国家高级计算应用中心(NCSA)开发,具有以下特点:
- 分层结构(类似文件系统中的目录结构)
- 支持多种数据类型
- 跨平台兼容
- 支持并行I/O
- 提供数据压缩和分块存储
HDF5数据类型
HDF5支持丰富的数据类型,主要分为两类:
1. 基本数据类型
- 整数类型:H5T_STD_I8, H5T_STD_I16, H5T_STD_I32, H5T_STD_I64(有符号)
- 无符号整数:H5T_STD_U8, H5T_STD_U16, H5T_STD_U32, H5T_STD_U64
- 浮点类型:H5T_IEEE_F32, H5T_IEEE_F64
- 字符串类型:定长或变长字符串
- 复合类型:类似C语言中的结构体
- 枚举类型
- 数组类型
- 变长数据类型
2. 派生数据类型
用户可以根据需要创建更复杂的数据类型:
- 复合类型(结构体)
- 数组类型
- 枚举类型
- 变长类型
- 不透明类型
HDF5读写功能
HDF5库提供的主要功能包括:
- 文件操作:创建、打开、关闭文件
- 组操作:创建、遍历组(类似目录)
- 数据集操作:创建、读写数据集(类似多维数组)
- 属性操作:为组或数据集添加元数据
- 数据类型操作:创建和管理数据类型
- 存储管理:分块、压缩、分片存储
HDF5读写示例程序(C语言)
示例1:创建HDF5文件并写入数据集
#include <hdf5.h>
#include <stdio.h>
#define FILE_NAME "example.h5"
#define DATASET_NAME "IntArray"
#define DIM0 4
#define DIM1 6
int main() {
hid_t file_id, dataset_id, dataspace_id;
herr_t status;
hsize_t dims[2] = {DIM0, DIM1};
int data[DIM0][DIM1];
// 初始化数据
for (int i = 0; i < DIM0; i++)
for (int j = 0; j < DIM1; j++)
data[i][j] = i * DIM1 + j + 1;
// 创建新HDF5文件
file_id = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
// 创建数据空间
dataspace_id = H5Screate_simple(2, dims, NULL);
// 创建数据集
dataset_id = H5Dcreate2(file_id, DATASET_NAME, H5T_STD_I32LE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
// 写入数据
status = H5Dwrite(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
// 关闭资源
status = H5Dclose(dataset_id);
status = H5Sclose(dataspace_id);
status = H5Fclose(file_id);
printf("HDF5文件创建成功,数据已写入。\n");
return 0;
}
示例2:读取HDF5文件中的数据
#include <hdf5.h>
#include <stdio.h>
#define FILE_NAME "example.h5"
#define DATASET_NAME "IntArray"
#define DIM0 4
#define DIM1 6
int main() {
hid_t file_id, dataset_id;
herr_t status;
int data[DIM0][DIM1];
// 打开现有HDF5文件
file_id = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT);
// 打开数据集
dataset_id = H5Dopen2(file_id, DATASET_NAME, H5P_DEFAULT);
// 读取数据
status = H5Dread(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
// 打印数据
printf("读取的数据内容:\n");
for (int i = 0; i < DIM0; i++) {
for (int j = 0; j < DIM1; j++)
printf("%3d ", data[i][j]);
printf("\n");
}
// 关闭资源
status = H5Dclose(dataset_id);
status = H5Fclose(file_id);
return 0;
}
示例3:使用压缩存储和属性
#include <hdf5.h>
#include <stdio.h>
#include <time.h>
#define FILE_NAME "compressed.h5"
#define DATASET_NAME "CompressedData"
#define DIM0 1000
#define DIM1 500
int main() {
hid_t file_id, dataset_id, dataspace_id, plist_id, attr_id, atype_id;
herr_t status;
hsize_t dims[2] = {DIM0, DIM1};
hsize_t chunk_dims[2] = {100, 100};
float data[DIM0][DIM1];
time_t current_time;
char time_str[50];
// 初始化数据
for (int i = 0; i < DIM0; i++)
for (int j = 0; j < DIM1; j++)
data[i][j] = (float)(i + j) / (i + j + 1);
// 创建新HDF5文件
file_id = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
// 创建数据空间
dataspace_id = H5Screate_simple(2, dims, NULL);
// 创建数据集创建属性列表,启用压缩和分块
plist_id = H5Pcreate(H5P_DATASET_CREATE);
status = H5Pset_chunk(plist_id, 2, chunk_dims);
status = H5Pset_deflate(plist_id, 6); // 设置压缩级别
// 创建数据集
dataset_id = H5Dcreate2(file_id, DATASET_NAME, H5T_IEEE_F32LE, dataspace_id,
H5P_DEFAULT, plist_id, H5P_DEFAULT);
// 写入数据
status = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
// 添加创建时间属性
current_time = time(NULL);
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", localtime(¤t_time));
atype_id = H5Tcopy(H5T_C_S1);
status = H5Tset_size(atype_id, strlen(time_str) + 1);
attr_id = H5Acreate2(dataset_id, "CreationTime", atype_id,
H5Screate(H5S_SCALAR), H5P_DEFAULT, H5P_DEFAULT);
status = H5Awrite(attr_id, atype_id, time_str);
// 关闭资源
status = H5Aclose(attr_id);
status = H5Tclose(atype_id);
status = H5Pclose(plist_id);
status = H5Dclose(dataset_id);
status = H5Sclose(dataspace_id);
status = H5Fclose(file_id);
printf("压缩的HDF5文件创建成功,数据已写入。\n");
return 0;
}
其他语言绑定
HDF5不仅支持C语言,还提供多种语言的API:
- Python:h5py或PyTables库
- C++:HDF5 C++ API
- Java:HDF5 Java绑定
- MATLAB:HDF5接口
- R:rhdf5包
Python示例(使用h5py)
import h5py
import numpy as np
# 创建文件并写入数据
with h5py.File('example_py.h5', 'w') as f:
data = np.arange(100).reshape(20, 5)
dset = f.create_dataset("mydata", data=data)
dset.attrs['description'] = "Example dataset created with Python"
# 读取数据
with h5py.File('example_py.h5', 'r') as f:
data_read = f['mydata'][:]
print("Data shape:", data_read.shape)
print("Description:", f['mydata'].attrs['description'])
总结
HDF5是一种强大的科学数据存储格式,具有以下优势:
- 支持大型复杂数据集
- 高效的分块和压缩存储
- 丰富的元数据支持(属性)
- 跨平台兼容性
- 多种编程语言支持
通过合理使用HDF5,可以有效地组织、存储和访问大规模科学数据。