HDF5中保存包含固定长度和可变长度字符串的DataSet

#include <hdf5.h>

const char* HOLDINGSET = "Holding";
const int RECORDCOUNT = 2;
const int CUSIPLEN = 9;

/* First structure  and dataset*/
typedef struct {
 char   *HoldingName;
 int    Shares;
 double MarketValue;
 char   CUSIP[CUSIPLEN];
} Holding;

void WriteHDF5Exam(const char* fileName)
{
 hid_t      file, dataset, space;  // Handles
 herr_t     status;
 hsize_t    dim[] = { RECORDCOUNT };    // Dataspace dimensions

 // Initialize the data
 Holding s1[RECORDCOUNT] = {
  { "MSCI", 1000, 42134, "ddd" },
  { "JP Morgan", 30, 3900, "ffff" }
 };
 //for (int i = 0; i< LENGTH; i++) {
 // s1[i].HoldingName = (char*)malloc(100);
 // sprintf_s(s1[i].HoldingName, 100, "Holding Name: %d", i);

 // s1[i].Shares = i;
 // s1[i].MarketValue = 1./(i+1);

 // sprintf_s(s1[i].CUSIP, CUSIPLen, "CUSIP:%d", i);
 //}

 // Create the data space
 space = H5Screate_simple(1, dim, NULL);

 // Create the file
 file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

 // Create the memory datatype
 hid_t t_str = H5Tcopy(H5T_C_S1);
 H5Tset_size(t_str, CUSIPLEN);

 hid_t t_string = H5Tcopy(H5T_C_S1);
 H5Tset_size(t_string, H5T_VARIABLE);

 hid_t holding_tid = H5Tcreate (H5T_COMPOUND, sizeof(Holding));
 H5Tinsert(holding_tid, "HoldingName", HOFFSET(Holding, HoldingName), t_string);
 H5Tinsert(holding_tid, "Shares", HOFFSET(Holding, Shares), H5T_NATIVE_INT);
 H5Tinsert(holding_tid, "MarketValue", HOFFSET(Holding, MarketValue), H5T_NATIVE_DOUBLE);
 H5Tinsert(holding_tid, "CUSIP", HOFFSET(Holding, CUSIP), t_str);

 // Create the dataset.
 dataset = H5Dcreate(file, HOLDINGSET, holding_tid, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

 // Write data to the dataset
 status = H5Dwrite(dataset, holding_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s1);

 // Release resources
 H5Tclose(holding_tid);
 H5Sclose(space);
 H5Dclose(dataset);
 H5Fclose(file);
}

void ReadHDF5Exam(const char* fileName)
{
 hid_t      file, dataset, space;  // Handles
 herr_t     status;
 int i;

 typedef struct {
  double c;
  int    a;
 } s2_t;
 s2_t       s2[RECORDCOUNT];
 hid_t      s2_tid;

 typedef struct {
  char   CUSIP[9];
 } s3_t;
 hid_t      s3_tid;
 s3_t       s3[RECORDCOUNT];

 typedef struct {
  char* HoldingName;
 } s4_t;
 hid_t     s4_tid;
 s4_t      s4[RECORDCOUNT];

 // Open the file and the dataset
 file = H5Fopen(fileName, H5F_ACC_RDONLY, H5P_DEFAULT);
 dataset = H5Dopen(file, HOLDINGSET, H5P_DEFAULT);

 s2_tid = H5Tcreate(H5T_COMPOUND, sizeof(s2_t));

 H5Tinsert(s2_tid, "MarketValue", HOFFSET(s2_t, c), H5T_NATIVE_DOUBLE);
 H5Tinsert(s2_tid, "Shares", HOFFSET(s2_t, a), H5T_NATIVE_INT);

 status = H5Dread(dataset, s2_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s2);

 printf("\n");
 printf("Field c : \n");
 for(i = 0; i < RECORDCOUNT; i++) printf("%.4f, ", s2[i].c);
 printf("\n");

 printf("\n");
 printf("Field a : \n");
 for( i = 0; i < RECORDCOUNT; i++) printf("%d, ", s2[i].a);
 printf("\n");

 hid_t t_str = H5Tcopy(H5T_C_S1);
 H5Tset_size(t_str, CUSIPLEN);

 s3_tid = H5Tcreate(H5T_COMPOUND, sizeof(s3_t));
 status = H5Tinsert(s3_tid, "CUSIP", 0, t_str);

 status = H5Dread(dataset, s3_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s3);

 printf("\n");
 printf("Field b : \n");
 for( i = 0; i < RECORDCOUNT; i++) printf("%s, ", s3[i].CUSIP);
 printf("\n");


 hid_t t_string = H5Tcopy(H5T_C_S1);
 H5Tset_size(t_string, H5T_VARIABLE);

 s4_tid = H5Tcreate(H5T_COMPOUND, sizeof(s4_t));
 status = H5Tinsert(s4_tid, "HoldingName", 0, t_string);

 status = H5Dread(dataset, s4_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s4);

 printf("\n");
 printf("Field b : \n");
 for( i = 0; i < RECORDCOUNT; i++) printf("%s, ", s4[i].HoldingName);
 printf("\n");


 // Release resources
 H5Tclose(s2_tid);
 H5Tclose(s3_tid);
 H5Dclose(dataset);
 H5Fclose(file);
}

 

你可以使用HDF5 C++ API来读取HDF5文件的数据。下面是一个简单的示例代码,可以读取HDF5文件名为"info"和"data"的两个数据集: ```c++ #include <iostream> #include <string> #include "H5Cpp.h" const std::string FILE_NAME("your_file_name.h5"); const std::string INFO_DATASET_NAME("info"); const std::string DATA_DATASET_NAME("data"); int main() { // Open the HDF5 file H5::H5File file(FILE_NAME, H5F_ACC_RDONLY); // Read the "info" dataset H5::DataSet info_dataset = file.openDataSet(INFO_DATASET_NAME); H5::DataSpace info_dataspace = info_dataset.getSpace(); // Get the number of elements in the dataset int info_size = info_dataspace.getSimpleExtentNpoints(); // Allocate memory to hold the data char* info_buf = new char[info_size+1]; // Read the data from the dataset into the memory buffer info_dataset.read(info_buf, H5::PredType::NATIVE_CHAR); // Null-terminate the string info_buf[info_size] = '\0'; // Print the info string std::cout << "info: " << info_buf << std::endl; // Clean up the memory delete[] info_buf; // Read the "data" dataset H5::DataSet data_dataset = file.openDataSet(DATA_DATASET_NAME); H5::DataSpace data_dataspace = data_dataset.getSpace(); // Get the dimensions of the dataset int ndims = data_dataspace.getSimpleExtentNdims(); hsize_t dims[ndims]; data_dataspace.getSimpleExtentDims(dims); // Allocate memory to hold the data double* data_buf = new double[dims[0]*dims[1]]; // Define the hyperslab that we want to read hsize_t offset[2] = {0, 0}; hsize_t count[2] = {dims[0], dims[1]}; data_dataspace.selectHyperslab(H5S_SELECT_SET, count, offset); // Define the memory dataspace H5::DataSpace mem_dataspace(ndims, dims); // Read the data from the dataset into the memory buffer data_dataset.read(data_buf, H5::PredType::NATIVE_DOUBLE, mem_dataspace, data_dataspace); // Print the data std::cout << "data:" << std::endl; for (int i = 0; i < dims[0]; i++) { for (int j = 0; j < dims[1]; j++) { std::cout << data_buf[i*dims[1]+j] << " "; } std::cout << std::endl; } // Clean up the memory delete[] data_buf; return 0; } ``` 上述代码使用了H5Cpp.h头文件定义的C++类来读取HDF5文件的数据。首先,我们打开文件并读取"info"和"data"数据集。对于"info"数据集,我们直接将数据读取到一个char数组,然后用cout输出即可。对于"data"数据集,我们需要手动定义一个内存缓冲区,并使用selectHyperslab方法来指定需要读取的数据范围。最后,我们将数据读取到内存缓冲区,并输出到控制台。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值