成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux下程序啟動之后的初始化---檢查配置文件及讀取日志配置項的值

開發 開發工具
在程序進行具體的操作之前,一些初始化操作是必不可少的。本文中的示例只是涉及到檢查配置文件和讀取日志配置項兩個操作,在實際的應用中可能還會有初始化數據庫參數、建立與其他模塊的通信鏈路等操作,這要視不同的程序而定。

概述

最近,我對本開發組的幾位新員工所編寫的程序進行了代碼走查,發現他們的代碼都有一個共同的問題:缺少必要的初始化。在本文中,我將詳細介紹程序在啟動時所必須要進行的初始化操作,并用實際的C代碼予以說明。

對于一般的程序來說,在啟動時所必須要進行的初始化操作有兩個:檢查配置文件及讀取日志配置項。對于檢查配置文件,主要檢查配置文件是否是規定的文件類型(后綴是否正確)及是否存放在了規定的目錄下(一般存放在當前用戶的etc目錄下);對于讀取日志配置項,主要將寫日志文件相關的參數(如日志級別、日志文件最大長度、最大備份日志文件數量等)從配置文件的日志段中讀取出來,放到全局變量中,以便后續流程使用。

可以用如下的流程圖來形象地表示程序的整個流程:

從上圖可以看出,程序啟動之后,如果檢查配置文件和讀取日志配置項兩者之一不通過,那么程序就不會執行后續流程。由此也可以看到,初始化操作在程序中的重要地位。下面我們用實際的C代碼來說明上圖中所示的兩個初始化操作。

程序代碼

為了便于說明,假設我們的主程序文件名為InitEnv.c,配置文件名為InitEnv.ini。同時,因為要從配置文件中讀取日志配置項的值,我們編寫GetConfig.c和GetConfig.h文件來提供從文件中讀取配置項值的操作(也就是API)。三個文件的代碼內容如下:

InitEnv.c:

  1. /********************************************************************** 
  2. * 版權所有 (C)2016, Zhou Zhaoxiong 
  3. * 文件名稱:InitEnv.c 
  4. * 文件標識:無 
  5. * 內容摘要:程序運行之前檢查配置文件和日志文件是否存在 
  6. * 其它說明:無 
  7. * 當前版本:V1.0 
  8. * 作   者:ZhouZhaoxiong 
  9. * 完成日期:20161213 
  10. **********************************************************************/ 
  11. #include "GetConfig.h" 
  12.  
  13. // 宏定義 
  14. #define INI_FILE_NAME  "InitEnv.ini" 
  15. #define LOG_FILE_NAME  "InitEnv.log" 
  16.  
  17. // 日志模塊全局參數結構 
  18. typedef struct 
  19.     UINT32    iLoglevel;                // 日志級別 
  20.     UINT32    iMaxLogSize;              // 日志文件最大長度 
  21.     UINT32    iMaxBakCount;             // 最大備份日志文件數量 
  22.     UINT32    iNewLogFileFlag;          // 啟動時是否新建空日志文件, 否則追加到上次的日志文件中,1-Yes 0-No 
  23.     UINT32    iLogPositionFlag;         // 是否輸出日志位置信息(文件名/行號),1-Yes 0-No 
  24.     UINT8     szLogFileFullName[256];   // 日志文件全路徑名稱 
  25. } T_LogInfo; 
  26. T_LogInfo t_loginfo = {0}; 
  27.  
  28.  
  29. // 函數聲明 
  30. INT32 AccessCfgFile(UINT8 *pszCfgFileName, UINT8 *pszCfgFileFullName); 
  31. INT32 InitLogInfo(UINT8 *pszCfgFileFullName); 
  32.  
  33.  
  34. /**************************************************************** 
  35. * 功能描述: 主函數 
  36. * 輸入參數: 無 
  37. * 輸出參數: 無 
  38. * 返 回 值: 0-執行完成 
  39. * 其他說明: 無 
  40. * 修改日期      版本號        修改人         修改內容 
  41. *------------------------------------------------------------- 
  42. * 20161213     V1.0     Zhou Zhaoxiong     創建 
  43. ****************************************************************/ 
  44. INT32 main(void) 
  45.     INT32 iRetVal                = 0; 
  46.     UINT8 szCfgFileFullName[256] = {0}; 
  47.  
  48.     // 首先檢查配置文件是否存在,并獲取帶全路徑的配置文件名 
  49.     iRetVal =AccessCfgFile(INI_FILE_NAME, szCfgFileFullName); 
  50.     if (iRetVal !=0)  // 配置文件不存在, 直接返回 
  51.     { 
  52.        printf("exec AccessCfgFile failed!\n"); 
  53.         return -1; 
  54.     } 
  55.  
  56.     // 打印獲取到的帶全路徑的配置文件名 
  57.     printf("CfgFileFullName is %s!\n", szCfgFileFullName); 
  58.  
  59.     // 然后讀取配置文件, 初始化日志信息 
  60.     iRetVal =InitLogInfo(szCfgFileFullName); 
  61.     if (iRetVal !=0)  // 讀取配置文件失敗, 直接返回 
  62.     { 
  63.        printf("exec InitLogInfo failed!\n"); 
  64.         return -1; 
  65.     } 
  66.  
  67.     // 打印初始化的日志信息 
  68.     printf("Loglevel is %d, MaxLogSize is %d(MB), MaxBakCount is %d,NewLogFileFlag is %d, LogPositionFlag is %d, LogFileFullName is %s!\n",t_loginfo.iLoglevel, t_loginfo.iMaxLogSize, t_loginfo.iMaxBakCount, 
  69.            t_loginfo.iNewLogFileFlag, t_loginfo.iLogPositionFlag,t_loginfo.szLogFileFullName); 
  70.  
  71.     return 0; 
  72.  
  73.  
  74. /**************************************************************** 
  75. * 功能描述: 檢查配置文件是否存在,并獲取帶全路徑的配置文件名 
  76. * 輸入參數: pszCfgFileName-不帶路徑的配置文件名 
  77. * 輸出參數: pszCfgFileFullName-帶全路徑的配置文件名 
  78. * 返 回 值: 0-存在 -1-不存在 -2-程序處理異常 
  79. * 其他說明: 無 
  80. * 修改日期      版本號         修改人       修改內容 
  81. *------------------------------------------------------------- 
  82. * 20161213     V1.0     Zhou Zhaoxiong     創建 
  83. ****************************************************************/ 
  84. INT32 AccessCfgFile(UINT8 *pszCfgFileName, UINT8*pszCfgFileFullName) 
  85.     UINT8  szTmpCfgFileName[256] = {0}; 
  86.     UINT8 *pFindStr              = NULL
  87.  
  88.     if (NULL ==pszCfgFileName || NULL == pszCfgFileFullName) 
  89.     { 
  90.        printf("AccessCfgFile: pszCfgFileName or pszCfgFileFullName isNULL!\n"); 
  91.         return -2; 
  92.     } 
  93.  
  94.     // 判斷配置文件的后綴是否為ini 
  95.     pFindStr =strstr(pszCfgFileName, ".ini"); 
  96.     if (pFindStr ==NULL)   // 配置文件后綴錯誤,直接返回 
  97.     { 
  98.        printf("AccessCfgFile: the suffix of %s is not ini, pleasecheck!\n", pszCfgFileName); 
  99.         return -2; 
  100.     } 
  101.  
  102.     // 獲取帶全路徑的配置文件名 
  103.    snprintf(szTmpCfgFileName, sizeof(szTmpCfgFileName)-1,"%s/etc/%s", getenv("HOME"), pszCfgFileName); 
  104.  
  105.     // 判斷配置文件是否存在 
  106.     if (0 == access(szTmpCfgFileName,F_OK))   // 配置文件存在 
  107.     { 
  108.        snprintf(pszCfgFileFullName, sizeof(szTmpCfgFileName)-1, "%s",szTmpCfgFileName); 
  109.     } 
  110.     else 
  111.     { 
  112.        printf("AccessCfgFile: %s has not existed!\n",szTmpCfgFileName); 
  113.         return -1; 
  114.     } 
  115.  
  116.     return 0; 
  117.  
  118.  
  119. /**************************************************************** 
  120. * 功能描述: 讀取配置文件, 初始化日志信息 
  121. * 輸入參數: pszCfgFileFullName-帶全路徑的配置文件名 
  122. * 輸出參數: 無 
  123. * 返 回 值: 0-處理成功 -1-處理失敗 
  124. * 其他說明: 無 
  125. * 修改日期       版本號       修改人        修改內容 
  126. ------------------------------------------------------------- 
  127. * 20161213     V1.0     Zhou Zhaoxiong     創建 
  128. ****************************************************************/ 
  129. INT32 InitLogInfo(UINT8 *pszCfgFileFullName) 
  130.     if (NULL ==pszCfgFileFullName) 
  131.     { 
  132.         printf("InitLogInfo:pszCfgFileFullName is NULL!\n"); 
  133.         return -1; 
  134.     } 
  135.  
  136.     // 日志級別0-Fatal 1-Error 2-Warn 3-Info 4-Trace 5-Debug 6-All 
  137.     t_loginfo.iLoglevel= GetConfigFileIntValue("LOG""LogLevel", 3,pszCfgFileFullName); 
  138.  
  139.     // 日志文件最大長度, 單位MB, 范圍是[1,500] 
  140.    t_loginfo.iMaxLogSize = GetConfigFileIntValue("LOG","LogMaxSize", 5, pszCfgFileFullName); 
  141.     if(t_loginfo.iMaxLogSize < 1 || t_loginfo.iMaxLogSize > 500) 
  142.     { 
  143.        t_loginfo.iMaxLogSize = 10;          // 配置超出[1,500]范圍默認10M 
  144.     } 
  145.  
  146.     // 最大備份日志文件數量, 范圍是[1,999] 
  147.     t_loginfo.iMaxBakCount = GetConfigFileIntValue("LOG","BackupCount", 10, pszCfgFileFullName); 
  148.     if(t_loginfo.iMaxBakCount < 1 || t_loginfo.iMaxBakCount > 999) 
  149.     { 
  150.        t_loginfo.iMaxBakCount = 10;    //配置超出[1,999]范圍默認10個 
  151.     } 
  152.  
  153.     // 每次啟動是否新建空日志文件 
  154.     t_loginfo.iNewLogFileFlag = GetConfigFileIntValue("LOG","NewLogFileFlag", 1, pszCfgFileFullName); 
  155.  
  156.     // 是否輸出日志位置信息(文件名/行號)標志 
  157.     t_loginfo.iLogPositionFlag = GetConfigFileIntValue("LOG","LogPositionFlag", 1, pszCfgFileFullName); 
  158.  
  159.     // 記錄日志文件全路徑名稱 
  160.      snprintf(t_loginfo.szLogFileFullName,sizeof(t_loginfo.szLogFileFullName)-1, "%s/log/%s",getenv("HOME"), LOG_FILE_NAME); 
  161.  
  162.     return 0; 

GetConfig.c:

  1. /********************************************************************** 
  2. * 版權所有 (C)2016, Zhou Zhaoxiong。 
  3. * 文件名稱:GetConfig.h 
  4. * 文件標識:無 
  5. * 內容摘要:Linux下配置文件的讀取 
  6. * 其它說明:無 
  7. * 當前版本:V1.0 
  8. * 作   者:ZhouZhaoxiong 
  9. * 完成日期:20161213 
  10. **********************************************************************/ 
  11. #include <stdio.h> 
  12. #include <stdlib.h> 
  13. #include <string.h> 
  14. #include <dirent.h> 
  15. #include <unistd.h> 
  16.  
  17.  
  18. // 數據類型重定義 
  19. typedef unsigned char   UINT8; 
  20. typedef signed   int    INT32; 
  21. typedef unsigned int    UINT32; 
  22.  
  23.  
  24. // 函數聲明 
  25. void GetStringContentValue(FILE *fp, UINT8 *pszSectionName,UINT8 *pszKeyName, UINT8 *pszOutput, UINT32 iOutputLen); 
  26. void GetConfigFileStringValue(UINT8 *pszSectionName, UINT8*pszKeyName, UINT8 *pDefaultVal, UINT8 *pszOutput, UINT32 iOutputLen, UINT8*pszConfigFileName); 
  27. INT32 GetConfigFileIntValue(UINT8 *pszSectionName, UINT8*pszKeyName, UINT32 iDefaultVal, UINT8 *pszConfigFileName); 

GetConfig.c:

  1. /********************************************************************** 
  2. * 版權所有 (C)2016, Zhou Zhaoxiong。 
  3. * 文件名稱:GetConfig.c 
  4. * 文件標識:無 
  5. * 內容摘要:Linux下配置文件的讀取 
  6. * 其它說明:無 
  7. * 當前版本:V1.0 
  8. * 作   者:ZhouZhaoxiong 
  9. * 完成日期:20161213 
  10. **********************************************************************/ 
  11. #include "GetConfig.h" 
  12.  
  13.  
  14. /********************************************************************** 
  15. * 功能描述:獲取具體的字符串值 
  16. * 輸入參數: fp-配置文件指針 
  17.            pszSectionName-段名, 如: GENERAL 
  18.            pszKeyName-配置項名, 如:EmployeeName 
  19.            iOutputLen-輸出緩存長度 
  20. * 輸出參數: pszOutput-輸出緩存 
  21. * 返 回 值:無 
  22. * 其它說明:無 
  23. * 修改日期        版本號         修改人        修改內容 
  24. *------------------------------------------------------------------ 
  25. * 20161213       V1.0     Zhou Zhaoxiong     創建 
  26. ********************************************************************/ 
  27. void GetStringContentValue(FILE *fp, UINT8 *pszSectionName,UINT8 *pszKeyName, UINT8 *pszOutput, UINT32 iOutputLen) 
  28.     UINT8  szSectionName[100]    = {0}; 
  29.     UINT8  szKeyName[100]        = {0}; 
  30.     UINT8  szContentLine[256]    = {0}; 
  31.     UINT8  szContentLineBak[256] = {0}; 
  32.     UINT32 iContentLineLen       = 0; 
  33.     UINT32 iPositionFlag         = 0; 
  34.  
  35.     // 先對輸入參數進行異常判斷 
  36.     if (fp == NULL ||pszSectionName == NULL || pszKeyName == NULL || pszOutput == NULL
  37.     { 
  38.        printf("GetStringContentValue: input parameter(s) isNULL!\n"); 
  39.         return
  40.     } 
  41.  
  42.     sprintf(szSectionName, "[%s]", pszSectionName); 
  43.     strcpy(szKeyName,pszKeyName); 
  44.  
  45.     while (feof(fp) ==0) 
  46.     { 
  47.        memset(szContentLine, 0x00, sizeof(szContentLine)); 
  48.        fgets(szContentLine, sizeof(szContentLine), fp);      // 獲取段名 
  49.  
  50.         // 判斷是否是注釋行(以;開頭的行就是注釋行)或以其他特殊字符開頭的行 
  51.         if(szContentLine[0] == ';' || szContentLine[0] == '\r' || szContentLine[0] =='\n' || szContentLine[0] == '\0'
  52.         { 
  53.             continue
  54.         } 
  55.  
  56.         // 匹配段名 
  57.         if(strncasecmp(szSectionName, szContentLine, strlen(szSectionName)) == 0)     
  58.         { 
  59.             while(feof(fp) == 0) 
  60.             { 
  61.                memset(szContentLine,    0x00,sizeof(szContentLine)); 
  62.                memset(szContentLineBak, 0x00, sizeof(szContentLineBak)); 
  63.                fgets(szContentLine, sizeof(szContentLine), fp);     // 獲取字段值 
  64.  
  65.                 // 判斷是否是注釋行(以;開頭的行就是注釋行) 
  66.                 if(szContentLine[0] == ';'
  67.                 { 
  68.                    continue
  69.                 } 
  70.  
  71.                memcpy(szContentLineBak, szContentLine, strlen(szContentLine)); 
  72.  
  73.                 // 匹配配置項名 
  74.                 if(strncasecmp(szKeyName, szContentLineBak, strlen(szKeyName)) == 0)     
  75.                 { 
  76.                    iContentLineLen = strlen(szContentLine); 
  77.                     for(iPositionFlag = strlen(szKeyName); iPositionFlag <= iContentLineLen;iPositionFlag ++) 
  78.                     { 
  79.                        if (szContentLine[iPositionFlag] == ' '
  80.                        { 
  81.                            continue
  82.                        } 
  83.                        if (szContentLine[iPositionFlag] == '='
  84.                        { 
  85.                            break; 
  86.                         } 
  87.  
  88.                        iPositionFlag = iContentLineLen + 1; 
  89.                        break; 
  90.                     } 
  91.  
  92.                    iPositionFlag = iPositionFlag + 1;   // 跳過=的位置 
  93.  
  94.                     if(iPositionFlag > iContentLineLen) 
  95.                     { 
  96.                        continue
  97.                     } 
  98.  
  99.                    memset(szContentLine, 0x00, sizeof(szContentLine)); 
  100.                    strcpy(szContentLine, szContentLineBak + iPositionFlag); 
  101.  
  102.                     // 去掉內容中的無關字符 
  103.                     for(iPositionFlag = 0; iPositionFlag < strlen(szContentLine); iPositionFlag ++) 
  104.                     { 
  105.                        if (szContentLine[iPositionFlag] == '\r' || szContentLine[iPositionFlag]== '\n' || szContentLine[iPositionFlag] == '\0'
  106.                        { 
  107.                            szContentLine[iPositionFlag] = '\0'
  108.                            break; 
  109.                        } 
  110.                     } 
  111.  
  112.                     // 將配置項內容拷貝到輸出緩存中 
  113.                    strncpy(pszOutput, szContentLine, iOutputLen-1); 
  114.                    break; 
  115.                 } 
  116.                 else if(szContentLine[0] == '['
  117.                 { 
  118.                    break; 
  119.                 } 
  120.             } 
  121.             break; 
  122.         } 
  123.     } 
  124.  
  125.  
  126. /********************************************************************** 
  127. * 功能描述:從配置文件中獲取字符串 
  128. * 輸入參數: pszSectionName-段名, 如:GENERAL 
  129.            pszKeyName-配置項名, 如:EmployeeName 
  130.            pDefaultVal-默認值 
  131.            iOutputLen-輸出緩存長度 
  132.            pszConfigFileName-配置文件名 
  133. * 輸出參數: pszOutput-輸出緩存 
  134. * 返 回 值:無 
  135. * 其它說明:無 
  136. * 修改日期       版本號         修改人       修改內容 
  137. *------------------------------------------------------------------ 
  138. * 20161213      V1.0     Zhou Zhaoxiong     創建 
  139. ********************************************************************/  
  140. void GetConfigFileStringValue(UINT8 *pszSectionName, UINT8*pszKeyName, UINT8 *pDefaultVal, UINT8 *pszOutput, UINT32 iOutputLen, UINT8*pszConfigFileName) 
  141.     FILE  *fp                    = NULL
  142.     UINT8  szWholePath[256]      = {0}; 
  143.  
  144.     // 先對輸入參數進行異常判斷 
  145.     if (pszSectionName== NULL || pszKeyName == NULL || pszOutput == NULL || pszConfigFileName ==NULL
  146.     { 
  147.         printf("GetConfigFileStringValue: input parameter(s) isNULL!\n"); 
  148.         return
  149.     } 
  150.  
  151.     // 獲取默認值 
  152.     if (pDefaultVal ==NULL
  153.     { 
  154.        strcpy(pszOutput, ""); 
  155.     } 
  156.     else 
  157.     { 
  158.        strcpy(pszOutput, pDefaultVal); 
  159.     } 
  160.  
  161.     // 打開配置文件 
  162.     fp =fopen(pszConfigFileName, "r"); 
  163.     if (fp == NULL
  164.     { 
  165.         printf("GetConfigFileStringValue: open %s failed!\n",szWholePath); 
  166.         return
  167.     } 
  168.  
  169.     // 調用函數用于獲取具體配置項的值 
  170.    GetStringContentValue(fp, pszSectionName, pszKeyName, pszOutput,iOutputLen); 
  171.  
  172.     // 關閉文件 
  173.     fclose(fp); 
  174.     fp = NULL
  175.  
  176.  
  177. /********************************************************************** 
  178. * 功能描述:從配置文件中獲取整型變量 
  179. * 輸入參數:pszSectionName-段名, 如:GENERAL 
  180.           pszKeyName-配置項名, 如:EmployeeName 
  181.           iDefaultVal-默認值 
  182.           pszConfigFileName-配置文件名 
  183. * 輸出參數:無 
  184. * 返 回 值:iGetValue-獲取到的整數值  -1-獲取失敗 
  185. * 其它說明:無 
  186. * 修改日期        版本號        修改人       修改內容 
  187. *------------------------------------------------------------------ 
  188. * 20161213      V1.0     Zhou Zhaoxiong     創建 
  189. ********************************************************************/  
  190. INT32 GetConfigFileIntValue(UINT8 *pszSectionName, UINT8*pszKeyName, UINT32 iDefaultVal, UINT8 *pszConfigFileName) 
  191.     UINT8  szGetValue[512] = {0}; 
  192.     INT32  iGetValue       = 0; 
  193.  
  194.     // 先對輸入參數進行異常判斷 
  195.     if (pszSectionName== NULL || pszKeyName == NULL || pszConfigFileName == NULL
  196.     { 
  197.         printf("GetConfigFileIntValue: input parameter(s) isNULL!\n"); 
  198.         return -1; 
  199.     } 
  200.  
  201.    GetConfigFileStringValue(pszSectionName, pszKeyName, NULL, szGetValue,512-1, pszConfigFileName);    // 先將獲取的值存放在字符型緩存中 
  202.  
  203.     if (szGetValue[0] =='\0' || szGetValue[0] == ';')    // 如果是結束符或分號, 則使用默認值 
  204.     { 
  205.         iGetValue =iDefaultVal; 
  206.     } 
  207.     else 
  208.     { 
  209.         iGetValue =atoi(szGetValue); 
  210.     } 
  211.  
  212.     return iGetValue; 

程序說明

我們主要對InitEnv.c文件進行說明:

第一,檢查配置文件的操作是由AccessCfgFile函數完成的,該函數首先判斷配置文件的后綴是否為ini,然后獲取帶全路徑的配置文件名,最后判斷配置文件是否存在。如果該函數執行失敗(配置文件不存在或其他),那么直接停止程序的運行,不再執行后續流程。

第二,讀取日志配置項的操作是由InitLogInfo函數完成的,該函數從配置文件InitEnv.ini的[LOG]段中將LogLevel、LogMaxSize、BackupCount、NewLogFileFlag和LogPositionFlag配置項的值讀取出來。如果該函數執行失敗,那么直接停止程序的運行,不再執行后續流程。

第三,如果AccessCfgFile和InitLogInfo函數都執行成功,那么就意味著程序初始化成功了,可以執行后續操作。本程序的后續操作便是打印讀取到的配置項的值及日志文件全路徑名稱。

程序測試

我們將上述三個文件上傳到Linux機器上,并使用“gcc -g -o InitEnvInitEnv.c GetConfig.c”命令編譯之后,生成InitEnv文件。執行“InitEnv”命令,即可對程序進行測試。

1)當配置文件InitEnv.ini不存在或未被放置到規定目錄時,程序運行結果如下:

  1. AccessCfgFile: /home/zhou/etc/InitEnv.ini has not existed! 
  2. exec AccessCfgFile failed!1212 

2)當配置文件InitEnv.ini內容如下:

  1. [LOG] 
  2. ;LogLevel, 0-Fatal 1-Error 2-Warn 3-Info4-Trace 5-Debug 6-All 
  3. LogLevel=4  
  4.  
  5. ;Max log size (MB), [1,500] 
  6. LogMaxSize=10 
  7.  
  8. ;Max log backup count [1,999] 
  9. BackupCount=100 
  10.  
  11. ;If output log into new file when starting, 1-Yes 0-No 
  12. NewLogFileFlag=0 
  13.  
  14. ;If output position info(filename/linenum), 1-Yes 0-No 
  15. LogPositionFlag=1 

程序運行結果為:

  1. CfgFileFullName is /home/zhou/etc/InitEnv.ini! 
  2.  
  3. Loglevel is 4, MaxLogSize is 10(MB), MaxBakCount is 100,NewLogFileFlag is 0, LogPositionFlag is 1, LogFileFullName is /home/zhou/log/InitEnv.log!1212 

可見,在正常情況下,程序能夠完成檢查配置文件及讀取日志配置項的操作,大家也可以對程序進行更多的測試。

總結

在程序進行具體的操作之前,一些初始化操作是必不可少的。本文中的示例只是涉及到檢查配置文件和讀取日志配置項兩個操作,在實際的應用中可能還會有初始化數據庫參數、建立與其他模塊的通信鏈路等操作,這要視不同的程序而定。

“磨刀不誤砍柴工”,當程序完成了必要的初始化操作之后,便可以進行正式的操作了。

【本文是51CTO專欄作者周兆熊的原創文章,作者微信公眾號:周氏邏輯(logiczhou)】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: csdn博客
相關推薦

2010-02-05 09:31:23

Ubuntu 配置文件

2010-02-07 14:50:46

Ubuntu配置文件

2009-12-31 14:54:33

Ubuntu配置文件

2021-12-02 18:15:39

網絡庫Ratel設計

2013-07-30 11:30:42

Windows PhoWindows Pho

2011-01-13 16:27:26

Linux配置文件

2010-01-12 13:47:18

Linux grub

2023-10-30 15:11:57

2010-11-12 09:44:59

Cassandra配置

2023-08-07 16:14:32

propertiesSpring框架

2010-02-02 18:19:52

Linux mplay

2011-09-01 18:02:45

samba服務器

2010-01-08 15:13:44

交換機配置文件

2011-03-22 13:37:29

Nagios安裝

2011-03-25 17:13:37

Nagios配置文件

2011-02-25 16:39:34

proftpd配置文件

2016-11-11 00:33:25

雙重檢查鎖定延遲初始化線程

2009-08-13 09:58:55

C#讀取配置文件

2009-08-13 09:16:57

C#讀取配置文件

2010-08-02 16:58:08

Flex配置文件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线观看成人小视频 | 有码在线 | 国产激情精品视频 | 国产电影一区二区 | 台湾佬久久 | 日韩电影一区 | 精品一区二区三区四区外站 | 日韩国产精品一区二区三区 | aaa国产大片 | 亚洲一级淫片 | 亚洲成网 | 成人性视频在线播放 | 天天色av| 日韩欧美视频在线 | 欧美视频精品 | 中文字幕av高清 | 精品一区二区三区四区外站 | 欧美成人综合 | 中文字幕在线观看第一页 | 免费一级片| 亚洲成av片人久久久 | 中文字幕精品视频 | 日韩欧美国产精品 | 欧美成人高清 | 激情五月婷婷 | 国产精品亚洲一区二区三区在线观看 | 偷拍自拍网站 | 国外成人在线视频 | 久久9精品 | 中文字幕一区二区三区乱码在线 | 中文字幕国 | 日韩精品一区二区三区中文字幕 | 国产精品久久久亚洲 | 精品日本久久久久久久久久 | 亚洲精品视频导航 | 在线永久看片免费的视频 | 91亚洲精品久久久电影 | www.47久久青青 | 97超碰免费| 日韩欧美精品 | 欧美激情一区 |