使用 hiredis 客戶端批量寫入二進制鍵值對(mset)。標準 `redisCommand` 格式化字符串不支持二進制數據(遇 `\0` 截斷),需使用二進制安全接口 `redisCommandArgv`。
void msetNotBinary(redisContext* c, const vector& keys, const vector & vals) { string cmd = "MSET"; for (size_t i = 0; i < keys.size(); ++i) cmd += " " + keys[i] + " " + vals[i]; void* r = redisCommand(c, cmd.c_str()); // ... 錯誤處理 }
❌ 二進制數據會被截斷(如 `"AB\0DE"` 變為 `"AB"`)
void mset1(redisContext* c, const vector& keys, const vector & vals) { int argc = keys.size() + vals.size() + 1; char** argv = new char*[argc]; size_t* argvlen = new size_t[argc]; int j = 0; argv[j] = new char[5]; memcpy(argv[j], "MSET", 4); argvlen[j] = 4; ++j; for (size_t i = 0; i < keys.size(); ++i) { argvlen[j] = keys[i].size(); argv[j] = new char[argvlen[j]]; memcpy(argv[j], keys[i].data(), keys[i].size()); ++j; argvlen[j] = vals[i].size(); argv[j] = new char[argvlen[j]]; memcpy(argv[j], vals[i].data(), vals[i].size()); ++j; } void* r = redisCommandArgv(c, argc, const_cast (argv), argvlen); // ... 釋放內存 }
✅ 二進制安全 ✅ 但手動內存管理繁瑣,`char**` 到 `const char**` 轉換需 `const_cast` 有風險
void mset2(redisContext* c, const vector& keys, const vector & vals) { vector argv(keys.size() + vals.size() + 1); vector argvlen(keys.size() + vals.size() + 1); int j = 0; static const char* msetcmd = "MSET"; argv[j] = msetcmd; argvlen[j] = 4; ++j; for (size_t i = 0; i < keys.size(); ++i) { argvlen[j] = keys[i].size(); argv[j] = new char[argvlen[j]]; memcpy(argv[j], keys[i].data(), keys[i].size()); ++j; argvlen[j] = vals[i].size(); argv[j] = new char[argvlen[j]]; memcpy(argv[j], vals[i].data(), vals[i].size()); ++j; } void* r = redisCommandArgv(c, argv.size(), &argv[0], &argvlen[0]); // ... 釋放 new 出的 char* }
✅ 二進制安全 ✅ vector 自動管理指針數組生命周期 ✅ 代碼更清晰安全
# 非二進制安全:get D -> "AB" # 二進制安全: get D -> "AB\x00DE"
掌握 hiredis 二進制接口是構建高性能 Redis C++ 客戶端的關鍵技能。