Protobuffer如何在重复字段中添加和设置值

问题描述 投票:0回答:1

我想附加一个Info元素,并将其值填充到ServerReply中名为Info的重复原型字段中。我的protobuf消息定义如下:

message ServerReply{
    string status = 1;
    repeated Info files = 2;     
}

message Info{                          
    string state = 1;                      
    string filename = 2;
    int64 filesize = 3;
    int64 modified_time = 4;           
    int32 checksum = 5; 
}

在我的C ++代码中,我试图像这样构造它,但是我一直没有成功。构造的输出似乎会创建相同的初始条目。我不知道为什么。我相信Info *file_info = response->add_files();应该添加一个新条目并指向它。然后,我将使用该指针来设置值,如下所示:

/* Server constructs response to be send to client */
ServerReply* response;

// CODE HERE that loops through directory to Compute our file values (filesize, mtime, checksum etc)
DIR *dir;
struct dirent *entry;
struct stat st;
string folder = "/dir/to/server/folder/";
dir = opendir(folder);

// loop through our folder
while((entry = readdir(dir))){

    // get file details
    full_path = folder + entry->d_name;
    stat(full_path, &st);
    string filename = entry->d_name;
    int64_t filesize = st.st_size;
    int64_t modify_time = st.st_mtime;
    uint32_t checksum = get_file_checksum(full_path, &table_crc);

    // add empty element into our server reply
    Info *file_info = response->add_files();

    // set protobuff file data into empty ptr previously created 
    file_info->set_filename(filename);
    file_info->set_filesize(filesize);
    file_info->set_modified_time(modify_time);
    file_info->set_checksum(checksum);
}

为了确定我是否有正确的结果,我将存储的每个文件打印出构造好的响应。正如我们观察到的那样,同一条目被附加,而不是每个文件都被附加。

/* loop through */
ServerReply *response;

long list_size = response->files().size();
if( list_size > 0){
    cout << "files size: " << list_size << endl;

    auto file_entry = response->files().begin();

    while(file_entry != response->files().end()){
        cout << "Found File: " << file_entry->filename() 
             << " sz: " << file_entry->filesize() 
             << " mt: " << file_entry->modified_time()
             << " ck: " << file_entry->checksum() << endl;
    }
}

当前响应:

files size: 6
Found File: stackedd.png sz: 586637 mt: 1574584945 ck: 87542799
Found File: stackedd.png sz: 586637 mt: 1574584945 ck: 87542799
Found File: stackedd.png sz: 586637 mt: 1574584945 ck: 87542799
Found File: stackedd.png sz: 586637 mt: 1574584945 ck: 87542799
Found File: stackedd.png sz: 586637 mt: 1574584945 ck: 87542799
Found File: stackedd.png sz: 586637 mt: 1574584945 ck: 87542799

所需的控制台输出:

files size: 6
Found File: stackedd.png sz: 586637 mt: 1574584945 ck: 87542799
Found File: null.png sz: 0 mt: 1574243567 ck: 0
Found File: sora.jpg sz: 98721 mt: 1574621991 ck: 170695214
Found File: heartless.png sz: 84872 mt: 1574531828 ck: 1151753764
Found File: harrypotter.txt sz: 8242 mt: 1574243557 ck: 624749501
Found File: grokin_algo.png sz: 2387731 mt: 1574531830 ck: 1151753764
c++ arrays protocol-buffers
1个回答
0
投票

看来我追加到protobuffer的实现是正确的,但是我打印的方式是错误的。我没有正确遍历所有元素。要打印每个元素,我必须通过访问每个元素的索引来遍历每个元素。

int file_count = response->files().size();
cout << "Files: " <<  file_count << endl;
        for(int i = 0; i < file_count; i++){
            cout << "Found File: " << response->files(i).filename() 
                 << " size: " << response->files(i).filesize() 
                 << " last time modified: " << response->files(i).modified_time()
                 << " checksum: " << response->files(i).checksum() << endl;    
        }
© www.soinside.com 2019 - 2024. All rights reserved.