title: ecCodes索引访问
weight: 5
先介绍与索引访问有关的几个函数。
- 创建文件内容的索引
codes_index* codes_index_new_from_file(codes_context* c, char* filename,const char* keys,int *err);
- 从索引中获取某个 key 的维度
int codes_index_get_size(codes_index* index,const char* key,size_t* size);
- 从索引中获取 key 的不同“值”
int codes_index_get_long(codes_index* index,const char* key,long* values,size_t *size);int codes_index_get_double(codes_index* index,const char* key, double* values,size_t *size);int codes_index_get_string(codes_index* index,const char* key,char** values,size_t *size);
- 从索引中为某个 key 选择一个“值”
int codes_index_select_long(codes_index* index,const char* key,long value);int codes_index_select_double(codes_index* index,const char* key,double value);int codes_index_select_string(codes_index* index,const char* key,char* value);
- 加载与选择模型对应的 GRIB 消息
codes_handle* codes_handle_new_from_index(codes_index* index,int *err);
- 释放索引
void codes_index_delete(codes_index* index);
- 释放 GRIB 消息
int codes_handle_delete(codes_handle* h);
对于“随机访问”来说,使用索引访问通常比顺序访问更快。
示例:索引访问
#include <iostream>#include <eccodes.h>susing namespace std;int main(int argc, char** argv){if(argc < 2){cout<<"Usage: "<<argv[0]<<" grib_file_path";return 1;}const char* file_path = argv[1];int err = 0;codes_index* index = nullptr;index = codes_index_new(nullptr, "paramId", &err);if (err){cout<<"error: "<<codes_get_error_message(err)<<endl;exit(err);}err = codes_index_add_file(index, file_path);if (err){cout<<"error: " << codes_get_error_message(err)<<endl;exit(err);}cout<<"end indexing..."<<endl;size_t param_id_size;codes_index_get_size(index,"paramId", ¶m_id_size);auto param_id_array= new long[param_id_size];codes_index_get_long(index, "paramId", param_id_array, ¶m_id_size);for(int i=0; i < param_id_size; i++){auto param_id = param_id_array[i];codes_index_select_long(index, "paramId", param_id);codes_handle* h = nullptr;int count = 0;while ((h = codes_handle_new_from_index(index, &err)) != nullptr){count++;if (err){printf("error: %d\n",err);exit(err);}size_t short_name_length;codes_get_length(h, "shortName", &short_name_length);auto short_name = new char[short_name_length];codes_get_string(h, "shortName", short_name, &short_name_length);long level;codes_get_long(h,"level",&level);long number;codes_get_long(h,"number",&number);long step;codes_get_long(h,"step",&step);printf("shortName=%s ",short_name);printf("level=%ld ",level);printf("number=%ld ",number);printf("step=%ld \n",step);codes_handle_delete(h);delete [] short_name;}}codes_index_delete(index);return 0;}
输入/输出
索引可以保存到文件中,方便重复使用。
- 保存索引到文件
int codes_index_write(codes_index *index, const char *filename);
- 加载使用
codes_index_write创建的索引文件
codes_index* codes_index_read(codes_context* c,const char* filename,int *err);
正如前一节的示例所展示的,我们可以将数据文件的内容添加到索引中。
int codes_index_add_file(grib_index *index, const char *filename);
可以使用 ecCodes 命令行工具 grib_index_build 创建索引文件。
$ grib_index_build -o cli.index levels.grib2--- grib_index_build: processing levels.grib2--- grib_index_build: keys included in the index file cli.index:--- mars.param, mars.levelist--- mars.param = { 156, 130, 131, 132, 260238 }--- mars.levelist = { 1000, 975, 950 }--- 15 messages indexed
创建的索引文件是二进制文件。

使用 grib_dump -D <index_file> 查看索引文件的内容。
$ grib_dump -D cli.index***** FILE: cli.indexGRIB File: levels.grib2Index keys:key name = mars.paramvalues = 156, 130, 131, 132, 260238key name = mars.levelistvalues = 1000, 975, 950Index count = 15no messages found in cli.index
在练习章节中会介绍更详细的内容。
