h5py 中有数据变化时自动刷新的方法吗?

问题描述 投票:0回答:1

在h5py中,创建组或数据集时,磁盘中的文件不会改变,除非调用file.flush(),如何实现数据改变时自动刷新?

我可以包装 h5py.File,但它不适用于子组。

class MyH5py(h5py.File):
    def __init__(self, name, mode='r'):
        super(MyH5py, self).__init__(name, mode)

    def __setitem__(self, key, obj):
        super(MyH5py, self).__setitem__(key, obj)
        super(MyH5py, self).flush()

    def create_group(self, name, track_order=None):
        res = super(MyH5py, self).create_group(name, track_order)
        super(MyH5py, self).flush()
        return res

    def create_dataset(self, name, shape=None, dtype=None, data=None, **kwds):
        res = super(MyH5py, self).create_dataset(name, shape=None, dtype=None, data=None, **kwds)
        super(MyH5py, self).flush()
        return res

有没有人有类似的问题,如何解决?谢谢。

编辑:

添加示例:

fh = MyH5py('f.h5', 'a')
group = fh.create_group('group')
group['dataset'] = 1 # not work
# group['dataset'].file.flush() # work

import time
time.sleep(300)

运行代码,然后在python进程休眠时kill掉它,可以看到'group'在'f.h5'中但是'dataset'不存在。 原因是我只能将 flush() 添加到 MyH5py 类中的根组。

python h5py flush
1个回答
0
投票

首先,您应该在程序末尾有一个文件

close()
方法。当你干净地退出时,你会很幸运,Python 会为你完成这件事。关闭打开的文件是一种很好的做法。

最好使用Python的

with/as
上下文管理器打开文件。如果/当您异常退出时(由于程序崩溃或文件由于编码错误而未关闭),它将运行适当的拆卸过程(例如,关闭文件)。

不要这样做:

fh = h5py.File('f.h5', 'a')
group = fh.create_group('group')
dlist = [i for i in range(10)]
ds = group.create_dataset('test',data=dlist)
ds.flush() 
fh.close()  

相反,这样做:

with h5py.File('f.h5', 'a') as fh:
    group = fh.create_group('group')
    dlist = [i for i in range(10)]
    ds = group.create_dataset('test',data=dlist)
    ### ds.flush() ### NOT NEEDED
    ### fh.close() ### NOT NEEDED

从外部(从操作系统)杀死进程是极端事件(如系统崩溃或电源故障)。当发生这种情况时,我怀疑上下文管理器将无法执行拆卸过程。你为什么要那样做?

编辑:为了查看数据是否被刷新,我在我的程序中添加了一个

sleep(15)
行,并且能够在程序暂停时使用HDFView打开和查看H5文件。该组已创建并刷新。 (我还创建了一些属性并且可以看到它们。)因此,
flush()
操作正在运行。但是,这并不能保证它能在系统崩溃时正常工作。您的问题可能是由于终止进程时出错导致文件无法正常关闭。

顺便说一句,创建一个自定义类来管理所有 HDF5/h5py 文件进程可能会让人头疼(对你来说)。您将不得不复制其他 h5py 方法。例如,看起来您的

__setitem__()
方法应该创建属性(基于
key, obj
参数)。如果是这样,它不会。它创建名称为
key
且数据为
obj
的数据集。相反,您需要使用
.attrs()
方法。

© www.soinside.com 2019 - 2024. All rights reserved.