在C+;中打开HDF5文件的更好方法+; 我一直在试图找到一种方法来绕过HDF5C++绑定的一些缺点。目前,我的代码中充斥着类似于以下内容的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); }

在C+;中打开HDF5文件的更好方法+; 我一直在试图找到一种方法来绕过HDF5C++绑定的一些缺点。目前,我的代码中充斥着类似于以下内容的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); },c++,inheritance,hdf5,C++,Inheritance,Hdf5,这应该不是必需的——我只想打开一个文件进行读/写访问,如果它不存在,就创建它。另一个更棘手的问题是创建一个嵌套组(例如“/parent/group”),其中父组不一定存在。在Unix/Linux中,等价物是 mkdir -p parent/group 但是,在HDF5C++绑定中,创建一个不存在父组的组会引发异常。 出于这些原因,我一直在努力创建一个头文件来处理这些常见问题。我的第一个想法是简单地创建一组函数,例如,采用文件名和访问模式并返回H5::H5File对象,或者采用组名并返回组对象。

这应该不是必需的——我只想打开一个文件进行读/写访问,如果它不存在,就创建它。另一个更棘手的问题是创建一个嵌套组(例如“/parent/group”),其中父组不一定存在。在Unix/Linux中,等价物是

mkdir -p parent/group

但是,在HDF5C++绑定中,创建一个不存在父组的组会引发异常。

出于这些原因,我一直在努力创建一个头文件来处理这些常见问题。我的第一个想法是简单地创建一组函数,例如,采用文件名和访问模式并返回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() { }
当文件不存在时,程序仍然终止。第二个问题是我不确定第二个构造函数

H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
是否正确(即是否构造父类?)是否有方法让派生类捕获基类构造函数中的异常,然后为基类调用其他构造函数


更一般地说,有人能想出一种更好的、更优雅的方法来处理HDF5C++绑定的缺点吗?

< P>我更喜欢你创建一些简单的助手函数的最初想法——它会更简单,并且最小化你必须编写和文档的代码量。此外,为了确保正确的内存管理,您可以使用
shared\u 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);
}
//托管文件指针的typedef
typedef std::共享_ptr H5FilePtr;
//创建或打开文件
H5FilePtr创建或打开(常量std::string和fname)
{
H5::Exception::dontPrint();
H5::H5文件*文件=0;
试一试{
file=新的H5::H5文件(fname.c_str(),H5F_ACC_RDWR);
}捕获(常数H5::FileIException&){
file=newh5::H5文件(fname.c_str(),H5F_ACC_TRUNC);
}
返回H5FilePtr(文件);
}

但是,在HDF5C++绑定中,创建一个不存在父组的组会引发异常。

可以将链接创建属性列表设置为,并避免此异常。例如:

#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;
}

“另一个更棘手的问题是创建一个嵌套组(例如“/parent/group”),其中父组不一定存在。在Unix/Linux中,等效的方法是……”——您有没有找到一个很好的方法来做到这一点?如果给您一个嵌套组名,如“/parent/group/subgroup”,首先将其拆分为“/parent”、“/parent/group”和“/parent/group”“/父/组/子组”,然后尝试按顺序打开每一个。如果给定组不存在(在C++ API中,您将得到<代码> H5::FILILVIELUT< /COD>)我写了。最近有同样的问题。没有解决方案。在上面,我注意到H5::异常不是从STD::异常……这是使用C API的另一个论点,即使是在C++中编写。在面向对象C++ API中很多功能都被丢失了,一些设计选择,比如抛出。离子而不是设置标志,是相当烦人的。我没有看到任何地方记录,所以有时是这样一个宝藏。这个解决方法是我肯定要使用:)
#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;
}