C++ HDF5复合型本机与IEEE
我刚刚开始学习HDF5,对于为内存创建数据和为文件创建数据之间的区别,我有点困惑。有什么区别 在示例中,创建复合类型数据需要在内存中创建数据并将其放置在文件中:C++ HDF5复合型本机与IEEE,c++,c,hdf5,dataformat,C++,C,Hdf5,Dataformat,我刚刚开始学习HDF5,对于为内存创建数据和为文件创建数据之间的区别,我有点困惑。有什么区别 在示例中,创建复合类型数据需要在内存中创建数据并将其放置在文件中: /* * Create the memory data type. */ s1_tid = H5Tcreate (H5T_COMPOUND, sizeof(s1_t)); H5Tinsert(s1_tid, "a_name", HOFFSET(s1_t, a), H5T_NATIVE_INT); H5Tinsert(s1_tid
/*
* Create the memory data type.
*/
s1_tid = H5Tcreate (H5T_COMPOUND, sizeof(s1_t));
H5Tinsert(s1_tid, "a_name", HOFFSET(s1_t, a), H5T_NATIVE_INT);
H5Tinsert(s1_tid, "c_name", HOFFSET(s1_t, c), H5T_NATIVE_DOUBLE);
H5Tinsert(s1_tid, "b_name", HOFFSET(s1_t, b), H5T_NATIVE_FLOAT);
/*
* Create the dataset.
*/
dataset = H5Dcreate(file, DATASETNAME, s1_tid, space, H5P_DEFAULT);
/*
* Wtite data to the dataset;
*/
status = H5Dwrite(dataset, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s1);
但是,在另一个示例中,作者还为文件创建了一个复合数据,它指定了不同的数据类型。例如,在为内存创建数据类型时,serial\u no used typeH5T\u NATIVE\u INT,但在为文件创建数据类型时,serial\u no usedH5T\u STD\u I64BE。他为什么这样做
/*
* Create the compound datatype for memory.
*/
memtype = H5Tcreate (H5T_COMPOUND, sizeof (sensor_t));
status = H5Tinsert (memtype, "Serial number",
HOFFSET (sensor_t, serial_no), H5T_NATIVE_INT);
status = H5Tinsert (memtype, "Location", HOFFSET (sensor_t, location),
strtype);
status = H5Tinsert (memtype, "Temperature (F)",
HOFFSET (sensor_t, temperature), H5T_NATIVE_DOUBLE);
status = H5Tinsert (memtype, "Pressure (inHg)",
HOFFSET (sensor_t, pressure), H5T_NATIVE_DOUBLE);
/*
* Create the compound datatype for the file. Because the standard
* types we are using for the file may have different sizes than
* the corresponding native types, we must manually calculate the
* offset of each member.
*/
filetype = H5Tcreate (H5T_COMPOUND, 8 + sizeof (hvl_t) + 8 + 8);
status = H5Tinsert (filetype, "Serial number", 0, H5T_STD_I64BE);
status = H5Tinsert (filetype, "Location", 8, strtype);
status = H5Tinsert (filetype, "Temperature (F)", 8 + sizeof (hvl_t),
H5T_IEEE_F64BE);
status = H5Tinsert (filetype, "Pressure (inHg)", 8 + sizeof (hvl_t) + 8,
H5T_IEEE_F64BE);
/*
* Create dataspace. Setting maximum size to NULL sets the maximum
* size to be the current size.
*/
space = H5Screate_simple (1, dims, NULL);
/*
* Create the dataset and write the compound data to it.
*/
dset = H5Dcreate (file, DATASET, filetype, space, H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT);
status = H5Dwrite (dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
这两种方法的区别是什么?来自:
H5T_NATIVE_INT对应于C INT类型。在基于Intel的PC上,此类型与H5T_STD_I32LE相同,而在MIPS系统上,此类型与H5T_STD_I32BE相同
也就是说,H5T_NATIVE_INT在不同类型的处理器上具有不同的内存布局。如果您的数据仅在内存中使用,这意味着您的数据不会从本机中传出,则您可能希望使用H5T_NATIVE_INT以获得更好的性能
但是,如果您的数据将保存到文件中,并且将由不同的系统使用,则必须指定特定的int类型以保持数据可以正确读取,例如H5T_STD_I64BE或H5T_STD_I32LE。如果您使用H5T_NATIVE_INT,并且在基于Intel的PC上创建了数据文件,则该数字将保存为H5T_STD_I32LE。当MIPS系统使用此文件时,它会将数字读取为H5T_STD_I32BE,这是不期望的。这里的另一个答案是缺少一些关键思想,这使得使用HDF5数据类型看起来比实际更困难 首先,本机类型只是C类型映射到该平台上的别名(在构建HDF5库时会检测到)。如果您在代码中使用它们并查看使用h5dump工具创建的文件,您将不会看到本机数据类型,而是会看到真实的数据类型(H5T_STD_I32LE或诸如此类)。诚然,这些本机类型有点令人困惑,但它们便于在C类型和HDF5数据类型之间进行映射,而无需知道您所在系统的字节顺序 我想澄清的另一个误解是,库将在合理的情况下为您转换类型。如果数据集包含H5T_STD_I32BE值,并且在小端系统上声明I/O缓冲区为H5T_NATIVE_INT,HDF5库将为您将大端数据集整数转换为内存中的小端整数。您不需要自己执行字节交换 下面是一个简单的思考方法:
- 调用H5Dcreate()时声明数据集的存储数据类型
- 调用H5Dread()和H5Dwrite()时,可以声明I/O缓冲区的数据类型
根据我的解释:文件类型可以是原生类型;客户有责任在读回内容时进行映射。换句话说:“当MIPS系统使用此文件时,它将读取数字为H5T_STD_I32BE,这不是预期的。”不正确;客户端应该读回文件类型,并相应地创建内存布局。客户端应该期望字节顺序不匹配,并通过正确的映射来缓解它。该示例演示了文件字节顺序/布局与主机(内存)字节顺序/布局解耦。@StevenVarga如果使用H5T_NATIVE_INT,您不知道它是big-endian还是little-endian,除非您在某个地方放置了一个标志,说明字节顺序是什么。即使您知道实际的字节顺序,在加载所有数据后转换它们也不是一件小事。代码维护也很困难。为什么要麻烦?为什么不在保存到文件时使用显式字节顺序?