最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++訪問Redis的mset 二進制數(shù)據(jù)接口封裝方案

 更新時間:2015年07月01日 10:10:22   投稿:hebedich  
這篇文章主要介紹了C++訪問Redis的mset 二進制數(shù)據(jù)接口封裝方案的相關資料,需要的朋友可以參考下

需求

C++中使用hiredis客戶端接口訪問redis;
需要使用mset一次設置多個二進制數(shù)據(jù)

以下給出三種封裝實現(xiàn)方案;

簡單拼接方案

在redis-cli中,mset的語法是這樣的:

復制代碼 代碼如下:

/opt/colin$./redis-cli mset a 11 b 22 c 333

OK

按照這樣的語法拼接后,直接使用hiredis字符串接口redisCommand傳遞:

void msetNotBinary(redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal )
{
  if(vtKey.size() != vtVal.size())
  {
    throw runtime_error( "Redis error" );
  }

  string strCmd = "MSET";
  for(int i = 0; i < vtKey.size(); i++)
  {
    strCmd += " "+vtKey[i]+" "+vtVal[i];
  }
  cout << "strCmd:" << strCmd << endl;

  void * r = redisCommand(c, strCmd.c_str() );
  if ( !r )
    throw runtime_error( "Redis error" );
  freeReplyObject( r );
}

void do_test( redisContext *c )
{  
  vector<string> vtKey;
  vector<string> vtVal;

  vtKey.push_back("A");
  vtVal.push_back("AAAA");
  vtKey.push_back("B");
  vtVal.push_back("BBBB");
  vtKey.push_back("C");
  vtVal.push_back("CCCC");
  //add a binary data
  vtKey.push_back("D");
  vtVal.push_back("");
  char a[] = "ABCDE";
  a[2] = 0;
  vtVal[3].assign(a,5);

  try
  {
    msetNotBinary(c, vtKey, vtVal );
    //mset1( c, vtKey, vtVal );
    //mset2( c, vtKey, vtVal );
  }
  catch ( runtime_error & )
  {
    cout << "Error" << endl;
  }
}

int main(int argc, char *argv[])
{
  redisContext *c;

  c = redisConnect("127.0.0.1",6379);
  if (c->err)
   {
    cout << "Connection error: " << c->errstr << endl;
    return -1;
  }

  do_test(c);

  redisFree(c);

  return 0;
}

這種方式可以處理mset多個字符串數(shù)據(jù),但對于數(shù)據(jù)內容為二進制數(shù)據(jù)的無能為力;

redisCommandArgv接口傳遞 方案

對于多個參數(shù)傳遞,hiredis提供了以下接口,這個接口中最后一個參數(shù)是所有的傳入數(shù)據(jù)的內容長度,
就是說這個接口是二進制安全的:

void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
主要工作就是構造一個動態(tài)的二維數(shù)組char ** argv,其中涉及到char **到const char **的轉換,有一定的風險,
關于這一點前一篇文章已經(jīng)談到;

void mset1( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal )
{
  if(vtKey.size() != vtVal.size())
  {
    throw runtime_error( "Redis error" );
  }

  char ** argv = new char*[vtKey.size() + vtVal.size() + 1 ];
  size_t * argvlen = new size_t[vtKey.size() + vtVal.size() + 1 ];

  int j = 0;
  argv[j] = new char[5];
  memcpy(argv[j],"MSET",4);
  argvlen[j] = 4;
  ++j;


  for(int i = 0 ; i < vtKey.size();i++)
  {  
    argvlen[j] = vtKey[i].length();
    argv[j] = new char[argvlen[j]];
     memset((void*)argv[j],0,argvlen[j] );
    memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length());
    j++;

    argvlen[j] = vtVal[i].length();
    argv[j] = new char[argvlen[j]];
    memset((void*)argv[j],0,argvlen[j]);
    memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length());
    j++;
  }

  //if not use const_cast<const char**> ,compile error
  //for why assign from char** to const char** error, see my blog ...
   void *r = redisCommandArgv(c, vtKey.size() + vtVal.size() + 1, const_cast<const char**>(argv), argvlen );
  if ( !r )
    throw runtime_error( "Redis error" );
  freeReplyObject( r );

  for(int i = 0;i < vtKey.size();i++)
  {
    delete [] argv[i];
    argv[i] = NULL;
  }

  delete []argv;
  delete []argvlen;
  argv = NULL;
}

redisCommandArgv接口傳遞的Vector方案

還是使用redisCommandArgv接口,使用vector來構造這個const char **,這個方法是從參考資料1中學到的:

void mset2( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal)
{
  if(vtKey.size() != vtVal.size())
  {
    throw runtime_error( "Redis error" );
  }

  vector<const char *> argv( vtKey.size() + vtVal.size() + 1 );
  vector<size_t> argvlen( vtKey.size() + vtVal.size() + 1 );
  int j = 0;

  static char msetcmd[] = "MSET";
  argv[j] = msetcmd;
  argvlen[j] = sizeof(msetcmd)-1;
  ++j;

  for(int i = 0;i< vtKey.size();++i)
  {
    argvlen[j] = vtKey[i].length();
    argv[j] = new char[argvlen[j]];
     memset((void*)argv[j],0,argvlen[j] );
    memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length());
    j++;

    argvlen[j] = vtVal[i].length();
    argv[j] = new char[argvlen[j]];
    memset((void*)argv[j],0,argvlen[j]);
    memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length());
    j++;
  }

  void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) );
  if ( !r )
    throw runtime_error( "Redis error" );
  freeReplyObject( r );
}

這樣,就實現(xiàn)二進制數(shù)據(jù)的傳遞;

二進制校驗

程序執(zhí)行后,可以用redis-cli來驗證:

對于非二進制安全的實現(xiàn),二進制內容是截斷的:

復制代碼 代碼如下:

/opt/app/colin$./redis-cli get D
"AB"

而二進制安全的實現(xiàn)接口,二進制數(shù)據(jù)的0通過轉義方式顯示:

復制代碼 代碼如下:

/opt/app/colin$./redis-cli get D
"AB\x00DE"

完整可執(zhí)行的代碼詳見github:https://github.com/me115/cppset/tree/master/2DimArray

以上所述就是本文的全部內容了,希望大家能夠喜歡。

相關文章

  • C語言中qsort函數(shù)的介紹與用法實例

    C語言中qsort函數(shù)的介紹與用法實例

    C語言的標準庫提供了一個重要的排序函數(shù)qsort給C語言使用者使用,qsort函數(shù)將快速排序的算法封裝起來,這篇文章主要給大家介紹了關于C語言中qsort函數(shù)的介紹與用法的相關資料,需要的朋友可以參考下
    2021-09-09
  • C語言互換最大值與最小值的位置

    C語言互換最大值與最小值的位置

    大家好,本篇文章主要講的是C語言互換最大值與最小值的位置,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C語言中進行函數(shù)指針回調的實現(xiàn)步驟

    C語言中進行函數(shù)指針回調的實現(xiàn)步驟

    在 C 語言中,函數(shù)指針的回調是一種強大的編程技術,它允許我們在特定的事件發(fā)生或特定的條件滿足時,調用由用戶定義的函數(shù),這種機制增加了程序的靈活性和可擴展性,使得代碼更具通用性和可重用性,本文給大家介紹了C語言中進行函數(shù)指針回調的實現(xiàn)步驟,需要的朋友可以參考下
    2024-07-07
  • C語言中的函數(shù)指針學習筆記

    C語言中的函數(shù)指針學習筆記

    這篇文章主要介紹了C語言中的函數(shù)指針的一些學習知識點記錄,文中作者整理了一些比較interesting的函數(shù)指針用法,需要的朋友可以參考下
    2016-04-04
  • C語言判斷字符串長度的方法小結

    C語言判斷字符串長度的方法小結

    學過C/C++的人都知道,在C/C++中并沒有提供直接獲取數(shù)組長度的函數(shù),對于存放字符串的字符數(shù)組提供了一個strlen函數(shù)獲取其長度,那么對于其他類型的數(shù)組如何獲取他們的長度呢?本文給大家介紹了C語言判斷字符串長度的方法小結,需要的朋友可以參考下
    2024-08-08
  • C語言:變量的作用域和生命周期詳解

    C語言:變量的作用域和生命周期詳解

    這篇文章主要介紹了C++作用域與生命周期的相關資料,幫助大家更好的理解和學習c++,感興趣的朋友可以了解下,希望能夠給你帶來幫助
    2021-08-08
  • 歸并排序的遞歸實現(xiàn)與非遞歸實現(xiàn)代碼

    歸并排序的遞歸實現(xiàn)與非遞歸實現(xiàn)代碼

    以下是對歸并排序的遞歸實現(xiàn)與非遞歸實現(xiàn)代碼進行了詳細的介紹,需要的朋友可以過來參考下
    2013-08-08
  • C語言的字符空間與非字符空間你了解嗎

    C語言的字符空間與非字符空間你了解嗎

    這篇文章主要介紹了C語言的字符空間與非字符空間,本文給大家介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • C++實現(xiàn)LeetCode(118.楊輝三角)

    C++實現(xiàn)LeetCode(118.楊輝三角)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(118.楊輝三角),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • c/c++中變量的聲明和定義深入解析

    c/c++中變量的聲明和定義深入解析

    “聲明”為編譯服務,用于類型檢查 ;“定義”在運行時會分配空間,不能重復定義,同時具備聲明的功能
    2013-09-09

最新評論

石首市| 合肥市| 沙坪坝区| 利津县| 固镇县| 宽城| 崇州市| 进贤县| 大同市| 浦东新区| 土默特右旗| 洛南县| 祁东县| 诸暨市| 嘉义市| 娱乐| 杨浦区| 海宁市| 西和县| 金湖县| 环江| 大埔县| 正镶白旗| 若尔盖县| 昭觉县| 锡林浩特市| 突泉县| 鹤山市| 祁东县| 城固县| 鄂伦春自治旗| 安丘市| 曲阳县| 桦南县| 荆门市| 永靖县| 交口县| 磴口县| 赣榆县| 化州市| 原阳县|