Python中能否实时以字节流形式读取正在写入的HDF5数据?
h5py实现HDF5文件边写边读的方案
完全可以实现你要的亚秒级读取刚写入数据的需求,不需要自己解析字节流,用HDF5原生的*单写多读(SWMR, Single Writer Multiple Reader)*模式即可,h5py已经完整封装了对应的底层API,具体实现方式如下:
写入侧配置
- 创建文件时必须指定启用SWMR模式,同时设置库版本为最新:
import h5py import numpy as np # 开启SWMR模式创建文件 f = h5py.File("stream_data.h5", "w", libver="latest", swmr=True) - 需要追加写入的数据集要设置为可扩展的分块存储类型,不能用连续存储:
# 示例创建一个可无限扩展的二维数据集,第一维是数据条数,第二维是字段数 dset = f.create_dataset( "raw_data", shape=(0, 8), maxshape=(None, 8), dtype="float32", chunks=(100, 8) # chunk大小匹配单次写入的批量大小即可优化性能 ) - 每次写完一批数据后立即调用flush操作,把内存中的数据和元数据刷到磁盘,该操作耗时一般在毫秒级:
# 追加写入100条数据的示例 new_data = np.random.randn(100, 8).astype("float32") dset.resize(dset.shape[0] + 100, axis=0) dset[-100:] = new_data # 刷入磁盘,让读取侧可见 dset.flush()
读取侧配置
- 用SWMR只读模式打开文件:
f = h5py.File("stream_data.h5", "r", libver="latest", swmr=True) dset = f["raw_data"] - 需要拉取最新数据时,先调用refresh刷新数据集元数据,就能直接访问最新写入的内容:
# 刷新元数据,获取最新的数据集大小 dset.refresh() latest_data = dset[-100:] # 直接读取最新的100条数据
关于字节流读取的说明
不建议直接读取HDF5文件的原始字节流,HDF5的元数据和数据块是分开存储的,写入过程中元数据会动态更新,直接读字节流很容易拿到不一致的元数据,导致解析失败甚至文件损坏。SWMR模式是HDF5官方提供的安全边写边读方案,延迟完全可以控制在100ms以内,满足亚秒级的读取要求。
内容的提问来源于stack exchange,提问作者David Parks
相关产品推荐
相关产品推荐

