我一直试图想出办法解决HDF5 C ++绑定的一些缺点。目前,我的代码中充斥着类似于以下内容的try / catch块:
H5::Exception::dontPrint();
H5::H5File *file = NULL;
try {
file = new H5::H5File(fname.c_str(), H5F_ACC_RDWR);
} catch(H5::FileIException &file_exists_err) {
file = new H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
}
这不是必需的 - 我想要做的就是打开一个文件进行读/写访问,如果不存在,则创建它。另一个棘手的问题是创建嵌套组(例如“/ parent / group”),其中父组不一定存在。在Unix / Linux中,等效的是
mkdir -p parent/group
但是,在HDF5 C ++绑定中,创建其父组不存在的组会引发异常。
由于这些原因,我有动力创建一个头文件来处理这些常见问题。我的第一个想法是简单地创建一组函数,例如,采用文件名和访问模式并返回H5 :: H5File对象,或者获取组名并返回组对象。我认为这不太理想,因为它使得使用此头文件的程序员在返回的对象上调用“delete”,即使程序员从未在自己的代码中明确地调用“new”。这似乎要求内存泄漏。
因此,我的第二个想法是从H5 :: H5File和H5 :: H5Group创建一组派生类,其中构造函数在文件尚不存在时不会抛出异常,或者当组的父组执行时还不存在我对派生文件类的尝试如下:
namespace H5Utils {
class H5File : public H5::H5File {
public:
H5File(std::string fname);
~H5File();
};
}
H5Utils::H5File::H5File(std::string fname)
try : H5::H5File(fname.c_str(), H5F_ACC_RDWR)
{
std::cerr << "Opened existing file." << std::endl;
} catch(H5::FileIException &file_exists_err) {
std::cerr << "File does not exist. Creating new file." << std::endl;
H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
}
H5Utils::H5File::~H5File() { }
我遇到的问题是双重的。首先,构造函数中的try / catch块重新抛出由
创建的异常H5::H5File(fname.c_str(), H5F_ACC_RDWR)
当文件不存在时,程序仍然终止。第二个问题是我不确定第二个构造函数,
H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
是正确的(即它是否构造了父类?)是否有办法让派生类在基类的构造函数中捕获异常,然后为基类调用不同的构造函数?
更一般地说,任何人都可以想到更好/更优雅的方式来处理HDF5 C ++绑定的这些缺点吗?
答案 0 :(得分:7)
我更喜欢你最初创建一些简单的辅助函数的想法 - 它会更简单,并最大限度地减少你必须编写和编写的代码量。此外,为确保正确的内存管理,您可以使用shared_ptr
。
这是一个简单的包装函数,等同于您的初始示例:
// a typedef for our managed H5File pointer
typedef std::shared_ptr<H5::H5File> H5FilePtr;
// create or open a file
H5FilePtr create_or_open(const std::string& fname)
{
H5::Exception::dontPrint();
H5::H5File* file = 0;
try {
file = new H5::H5File(fname.c_str(), H5F_ACC_RDWR);
} catch(const H5::FileIException&) {
file = new H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
}
return H5FilePtr(file);
}
答案 1 :(得分:3)
但是,在HDF5 C ++绑定中,创建其父组不存在的组会引发异常。
您可以将链接创建属性列表设置为create missing intermediate groups,并避免此异常。例如:
#include "hdf5.h"
int main (void){
hid_t lcpl, file_id, group_id;
herr_t status;
unsigned flag=1;
lcpl = H5Pcreate(H5P_LINK_CREATE);
status = H5Pset_create_intermediate_group(lcpl, flag);
file_id = H5Fcreate("nested_groups.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
group_id = H5Gcreate( file_id, "/foo/bar/bop", lcpl, H5P_DEFAULT, H5P_DEFAULT );
H5Pclose(lcpl);
H5Gclose(group_id);
H5Fclose(file_id);
return status;
}