问题:我想使用内存映射的HDF5文件进行单元测试。是否可以从头开始创建它们?
状态:我已经阅读了HDF5文件图像操作document,并尝试应用它。根据所使用的确切参数,我得到一个无效的文件标识符(-1),或后续创建的数据集失败。
通常,我们的单元测试会编写新的测试文件,模仿用户将新创建的数据保存到磁盘上的文件中。所以还没有现有的文件。在阅读hdf5文件图像操作的文档时,假设设置了初始文件图像。我没有 - 因为我试图尽可能接近我的测试的实际用户场景。可以从空缓冲区创建这样的文件吗?
static const unsigned int FileSize = 1024 * 1024 * 100;
std::vector<unsigned char> buffer(FileSize, 0); // initialize buffer with zeroes
int flags = H5LT_FILE_IMAGE_DONT_COPY |
H5LT_FILE_IMAGE_OPEN_RW |
H5LT_FILE_IMAGE_DONT_RELEASE;
m_file = H5LTopen_file_image(static_cast<void*>(buffer.data()), buffer.size(), flags);
如果想要保留缓冲区的所有权,如示例中所示,我没有获得有效的文件ID。我怀疑HDF5中有一个错误,但遗憾的是留下了标志H5LT_FILE_IMAGE_DONT_COPY | H5LT_FILE_IMAGE_DONT_RELEASE输出也不起作用。
答案 0 :(得分:1)
显然,H5LTOpen_file_image包含了一些允许创建虚拟文件的调用。这是核心文件驱动程序的所有管理。可以通过将一些参数传递给核心文件驱动程序来检索所需的结果。
auto propertyList = H5Pcreate(H5P_FILE_ACCESS);
auto h5Result = H5Pset_fapl_core(propertyList, m_buffer.GetSize(), false);
assert(h5Result >= 0 && "H5Pset_fapl_core failed");
m_file = H5Fcreate(name, flags, H5P_DEFAULT, propertyList);
对H5Pset_fapl_core的调用的最后一个参数设置&#34;虚拟后备存储&#34;的布尔值。如果设置为false,则不会将文件内容写入磁盘。
请注意,最后我必须使用开头帖子中提到的文档中的所有高级技巧来真正使所有功能正常工作。该文档是一个很好的参考,但稍微过时(枚举在最新版本中有不同但相似的命名)。
答案 1 :(得分:0)
根据@FreekNossin的回答,这是使用c ++ API的更完整代码:
#include<H5Cpp.h>
/* create the HDF5 file image first */
H5::FileAccPropList accPList=H5::FileAccPropList::DEFAULT;
// https://confluence.hdfgroup.org/display/HDF5/H5P_SET_FAPL_CORE
herr_t h5err=H5Pset_fapl_core(accPList.getId(),/* memory increment size: 4M */1<<22,/*backing_store*/false);
if(h5err<0) throw std::runtime_error("H5P_set_fapl_core failed.");
H5::H5File h5file("whatever",H5F_ACC_TRUNC,H5::FileCreatPropList::DEFAULT,accPList);
/* add data like usual */
H5::Group grp=h5file.createGroup("somegroup");
/* ... */
/* get the image */
h5file.flush(H5F_SCOPE_LOCAL); // probably not necessary
ssize_t imgSize=H5Fget_file_image(h5file.getId(),NULL,0); // first call to determine size
std::vector<char> buf(imgSize);
H5Fget_file_image(h5file.getId(),buf.data(),imgSize); // second call to actually copy the data into our buffer
编辑:代码中有一个陷阱:如果两个线程打开相同的"whatever"
(伪)文件,则会抛出H5::FileIException: unable to truncate a file which is already open
。我使用的一种解决方法是将堆栈(线程本地)变量的地址放入名称中:
int _var=0;
std::string hdf5name(("whatever+std::to_string((uintptr_t)&_var)).c_str());