1. 程式人生 > >第一次使用linux並編寫了一個dump mysql的程式,記錄下簡單的步驟

第一次使用linux並編寫了一個dump mysql的程式,記錄下簡單的步驟

機器安裝linux redhat5.0 64位。客戶管理員給了我賬戶密碼,我用SecureCRT登入。

連線後:

ls  列表檔案,當然支援萬用字元

cd path 進入某個目錄   *SecureCRT中可以像window一樣複製路徑,比較方便。

cd .. 返回上層

cd ~ 切換到使用者目錄

cd / 切換到根目錄

rm -f aaa.zip  刪除檔案

rm -rf aaa 刪除目錄 r應該是迴圈的意思

reboot 重啟

date -s 12/31/2015 修改日期

zip -r abc.zip abc 壓縮

unzip abc.zip 解壓縮

rz    SecureCRT從本地傳檔案上去。一般用zip就行。注意看是否100%,0 error。遇到已經存在的檔案要先rm掉才能上傳。

sz aa.zip  從linux往本地下載一個檔案。下載的位置在win7的“下載”資料夾。

linux可執行檔案可以無後綴,或者 .o,  執行時就算在當前目錄也要輸入 ./abc  才能執行

如果提示Permission denied,則執行chmod 777 abc 修改許可權即可

安裝mysql可以直接下載rpm安裝包

MySQL-server-community-5.0.96-1.rhel5.x86_64.rpm

MySQL-client-community-5.0.96-1.rhel5.x86_64.rpm

安裝rpm包: rpm -ivh abc.rpm

注意:可能為了商業開發的穩定性,並未使用更高版本

為了開發必須有lib庫,這個安裝client是沒有的。我採用下載原始碼來安裝

下載mysql5.0.96的原始碼:mysql-5.0.96.tar.gz,解壓縮到某個path,然後su切換到root賬號,cd path
  然後執行:
  ./configure --prefix=/usr/local/mysql/ --without-server --with-named-curses-libs=/usr/lib/libncursesw.so.5
  注意看到:Thank you for choosing MySQL! 的提示才算成功否則百度錯誤提示解決

  執行:make
  執行:make install
  安裝後可以拷貝一份mysql的HEADER標頭檔案和lib庫檔案,到其他電腦上也方便

為了測試目的安裝的mysql沒有自動啟動,執行: mysqld --user=root 啟動它

mysql進入命令列。

use database 切換資料庫

show tables; 看錶名

exit 退出命令列

編寫c程式用vim工具

vim abc.c

進去預設是隻讀的,按i 進入編輯狀態,需要儲存時,按esc,進入命令模式按 :wq 儲存退出  :w只儲存不退出

程式編寫好後,我將其單獨放入一個資料夾內,並把mysql的標頭檔案和mysql的庫檔案放入HEADER和LIB資料夾,建立sh檔案便於快速編譯和執行

compile.sh  //編譯時用

#!/bin/sh
rm -f abc
cc -o abc abc.c -L ./LIB -lmysqlclient

說明: 第一行刪除可執行檔案,第二行編譯並用-L引數指定庫路徑。為了簡單我已經把原始碼編譯得到的mysq庫放入了單獨的資料夾,便於帶到其他地方。

run.sh //執行時用

#!/bin/sh
export LD_LIBRARY_PATH=./LIB:$LD_LIBRARY_PATH
cd usr/abc
find ./LOG -size +50M -exec rm {} \;
./abc | tee -a ./LOG/2.log

說明:第一行 指定lib,第二行切換到當前目錄,這樣定時任務時,不會說相對路徑找不到,第三行刪除日誌,當體積大於50M時,第四行執行並輸出過程為日誌檔案

如果用虛擬機器安裝的linux是啟動到桌面的,則開啟網路可以看到主機,輸入管理員賬戶密碼,就能開啟磁碟分割槽拷貝檔案。

預設是非root登入的,比如chen,只需要開啟終端,輸入: su 提示輸入密碼,就能切換到root,其他操作同上述。

最後說一下程式的目標:dump mysql的表同步到映象的資料庫中去。

查詢目標mysql上的information_schema中的tables表,得到某個表最後的同步時間,如果早於今天凌晨或者不存在這個表則呼叫命令列mysqldump匯出。最後用mysql命令連線遠端的目標主機執行匯入。之前其他人開發的拷貝程式不是閉環控制,在網路閃斷的情況下幾乎天天失敗,拷貝和匯入脫節,兩部分都未對最終結果負責。

為何要使用c來做這個簡單程式是因為客戶不需要這個機器安裝更多的東西,比如php。用c編寫比較簡單一點。不會額外增加什麼。

當然作為初識linux和c在linux,以及呼叫mysql程式設計,作為一個機會練習吧。

具體原始碼

/* auth : chen
   dt: 2015-06-20
   func: 實現從v3000拷貝表格及其資料到緩衝伺服器
*/


#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include </usr/include/sys/stat.h>
#include <./HEADER/mysql.h>

//延遲時間,這樣定時任務可以設定到統一的時間,但是拷貝過程會分佈到0-30分鐘之間。
//為了計算式中不被零除,預設1.
#define DELAY_MINUTE 1

//檔案最小體積
#define MIN_FILESIZE 595


struct _strc_tbllist{
 int type;   //1.固定表 2.月表 3.日表  11:固定表e_customer如果不存在頭天晚上9點之後的表,則更新
       //22.月表,但是每天要更新
 char tblnamePre[80];
 char tblnameNew[80];   
};

int printtime(){
  time_t now; //例項化time_t結構
  struct tm *timenow; //例項化tm結構指標
  time(&now);
  //time函式讀取現在的時間(國際標準時間非北京時間),然後傳值給now
  timenow = localtime(&now);
  //localtime函式把從time取得的時間now換算成你電腦中的時間(就是你設定的地區)
  printf("%04d-%02d-%02d %02d:%02d:%02d\n",1900+timenow->tm_year,timenow->tm_mon+1,timenow->tm_mday,
                    timenow->tm_hour,timenow->tm_min,timenow->tm_sec);
}

int gettime_yyyymm(char* dt,int AddDay){
  time_t now; //例項化time_t結構
  struct tm *timenow; //例項化tm結構指標
  time(&now);
 
  now += (86400*AddDay);
 
  //time函式讀取現在的時間(國際標準時間非北京時間),然後傳值給now
  timenow = localtime(&now); 
 
  sprintf(dt,"%04d%02d",1900+timenow->tm_year,timenow->tm_mon+1);
}

int gettime_yyyymmdd(char* dt,int AddDay){
  time_t now; //例項化time_t結構
  struct tm *timenow; //例項化tm結構指標
  time(&now);
  now += (86400*AddDay);
 
  //time函式讀取現在的時間(國際標準時間非北京時間),然後傳值給now
  timenow = localtime(&now);
 
  sprintf(dt,"%04d%02d%02d",1900+timenow->tm_year,timenow->tm_mon+1,timenow->tm_mday);
}

int gettime_yyyy_mm_dd(char* dt,int AddDay){
  time_t now; //例項化time_t結構
  struct tm *timenow; //例項化tm結構指標
  time(&now);
  now += (86400*AddDay);
 
  //time函式讀取現在的時間(國際標準時間非北京時間),然後傳值給now
  timenow = localtime(&now);
 
  sprintf(dt,"%04d-%02d-%02d",1900+timenow->tm_year,timenow->tm_mon+1,timenow->tm_mday);
}

int gettime_daynumber(){
  time_t now; //例項化time_t結構
  struct tm *timenow; //例項化tm結構指標
  time(&now);
  //time函式讀取現在的時間(國際標準時間非北京時間),然後傳值給now
  timenow = localtime(&now);
 
  return timenow->tm_mday;
}

int ReadConfig(char* CfgFile,char* PlatFormID,char* IP,char* Port,char* User,char* Pwd){
 //conf中的配置資訊
  FILE *fp;
  char StrLine[1024];
 
  if((fp = fopen(CfgFile,"r"))== NULL) //判斷檔案是否存在及可讀
  {
  printf("fopen [config file] error\n");
  return -1;
  }
  //read it
  int r = 0;
  while (!feof(fp))
 {
  r ++;
  //特別注意fgets包含了末尾的回車符\n,之前涉及到登入時一直存在問題。注意!!!
  fgets(StrLine,1024,fp);  //讀取一行
  StrLine[strlen(StrLine) -1] = '\0';  //抹掉回車符號
  switch(r){
   case 12: //platform
    strcpy(PlatFormID,StrLine);
    printf("PlatFormID: %s\n", PlatFormID); //輸出
    break;
   case 14: //ip
    strcpy(IP,StrLine);
    printf("IP: %s\n",IP); //輸出
    break;
   case 16: //port
    strcpy(Port,StrLine);
    printf("Port: %s\n",Port); //輸出
    break;
   case 18: //User
    strcpy(User,StrLine);
    printf("User: %s\n", User); //輸出
    break;
   case 20:
    strcpy(Pwd,StrLine);
    printf("Pwd: %s\n", Pwd); //輸出
    break;
  }  
 }
 fclose(fp);
 return 1;
}


int ReadTableList(char* TableListFile,struct _strc_tbllist _tablelist[100]){
 //conf中的配置資訊
  FILE *fp;
  char StrLine[1024];
 
  if((fp = fopen(TableListFile,"r"))== NULL) //判斷檔案是否存在及可讀
  {
  printf("fopen [config file] error");
  return -1;
  }
  //read it
  int r = -1;
  int s;
  char tbltype[6];
  while (!feof(fp))
 {  
  //特別注意fgets包含了末尾的回車符\n,之前涉及到登入時一直存在問題。注意!!!
  fgets(StrLine,1024,fp);  //讀取一行
  StrLine[strlen(StrLine) -1] = '\0';  //抹掉回車符號

  if(r > -1){
   //找到開始{}一對括號作為開始和結束
   if(strcmp(StrLine,"}")==0){
    break; 
   }
   //輸出
   printf("Table List: %s\n",StrLine);    
   for(s = 0;s < strlen(StrLine);s++){
    if(StrLine[s] == ','){
     memset(tbltype,0,6);
     memcpy(tbltype,StrLine,s);
     
     //賦值
     _tablelist[r].type = atoi(tbltype);
     strcpy(_tablelist[r].tblnamePre,&StrLine[s+1]);
     break;
    }
   }
   r ++; 
  }else{
   //找到開始{}一對括號作為開始和結束
   if(strcmp(StrLine,"{")==0){
    r = 0;  //第一個
    continue; 
   }
  }   
 }
 fclose(fp);
 
 printf("Table Qty: %d\n\n",r);
 return r;
}


unsigned long get_filesize(const char *path){ 
 unsigned long filesize = -1;     
 struct stat statbuff; 
 if(stat(path, &statbuff) < 0){ 
  return filesize; 
 }else{ 
  filesize = statbuff.st_size; 
 } 
  return filesize; 


int main(int argc,char** argv){
 printf("\n\n\n-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
  printtime();
  printf("系統拷貝資料開始...\nbegin export and import...\n\n");
 
  //延遲執行,這樣每個伺服器可以分佈開
  srand((unsigned) time(NULL)); //用時間做種,每次產生隨機數不一樣
  int delay_second = 0;
  if(DELAY_MINUTE <= 1){
   //not delay 
  }else{
   delay_second = 60*(rand()% DELAY_MINUTE + 1);
   printf("將各臺伺服器執行時間分佈錯開: 延遲觸發 %d 秒++++++++++++++++\n",delay_second);
   sleep(delay_second);
  }
 
  //因為這個程式會從凌晨1點執行到早晨7點
  //7:30分執行更新動作
  //所以首先按table create time來判斷某個表是否成功建立,如未建立,加入到mysqldump的列表中去
 
  int TBL_QTY;
  struct _strc_tbllist tablelist[100];
 
  #define TBL_LISTS "./tables.tbl"
  TBL_QTY = ReadTableList(TBL_LISTS,tablelist);    

  //讀取配置檔案資訊
  #define CONFIG_FILE "./host.cfg"
  char PlatFormID[127],IP[127],User[127],Pwd[127];
  char Port[16];
  char DB_SCHEMA[64] = "information_schema";
  char DB_PLATFORM[64] = "v_";
 
  if(ReadConfig(CONFIG_FILE,PlatFormID,IP,Port,User,Pwd)<0){
   return -1;
  }                 
 
  //mysql init 
  MYSQL my_conn_schema; 
 MYSQL_RES *result; 
 int res;  
 mysql_init(&my_conn_schema);

 //連線到information_schema資料庫
 if(!mysql_real_connect(&my_conn_schema,IP,User,Pwd,DB_SCHEMA,60000,NULL,0)){   
  printf(">>>>>>>>connect [information_schema db] 失敗!\n原因: %s\n",mysql_error(&my_conn_schema));
  return -1;
 }
 
 //正常的提示
 printf("connect [information_schema db] 成功++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n");
  
 //排查fixed表
 char SQL[2048];
 char MyDump[1024],MyImport[1024];
 char ChangeDB[60];
 char SourcePath[60] = "./SQL_EXPORT/";
 char yyyymm[7],yyyymmdd[9],yyyy_mm_dd[11];
 int daysnumber; 
 char dt_tmp[10];
 //db name
 strcat(DB_PLATFORM,PlatFormID);
 
 //daysnumber
 daysnumber = gettime_daynumber();
  
 int beginday,endday;        //當天需要檢查多個表時使用。避免某天不成功第二天可以補救
 int t;
 int d;
 for(t = 0;t < TBL_QTY;t++){
  //區分某天拷貝哪些表  
  switch(tablelist[t].type){
   case 1:
    beginday = -1;  //只用執行一次內迴圈
    endday = 0;
    break;
   case 11:
    beginday = -1;  //只用執行一次內迴圈
    endday = 0;
    break;
   case 2:          //1-4號檢查,並且只檢查上個月的表
    //原則上,如果不是1號就不執行拷貝,實際條件下可能1號出問題,則1-4天都檢查一遍
    if(daysnumber >= 4){
     printf("此表只在1-4號檢查執行,跳過++++++++++++++++\n\n");
     continue;
    }
    beginday = (-1)*daysnumber;
    endday = (-1)*daysnumber +1;  //通過上限控制只執行一次
    break;
   case 22:
    //5-31號只判斷上月的
    if(daysnumber > 4){
     beginday = -1;
     endday = 0; 
    }
    //1-4號既要判斷上月的,又要判斷本月的
    if(daysnumber <= 4){
     beginday = (-1)*daysnumber;  //上個月的
     endday = 0;   //昨天的
    }
    break;
   case 3:
    beginday = -36;    //檢查31天內的未成功拷貝的表,這個表按名稱即可判斷不需要判斷匯入時間
    endday = 0;
    break;
   case 33:
    beginday = -36;    //檢查31天內的未成功拷貝的表,這個表按名稱即可判斷不需要判斷匯入時間
    endday = 0;
    break;   
  }
  
  for(d =beginday;d<endday;d++){   
   //不同型別的表需要動態新增字尾,比如20150601
   strcpy(tablelist[t].tblnameNew,tablelist[t].tblnamePre); 
   
   switch(tablelist[t].type){
    case 1:
     //do nothing 
     break;
    case 11:
     //do nothing 
     break;
    case 2:
     //增加月份字尾
     gettime_yyyymm(yyyymm,d);
     strcat(tablelist[t].tblnameNew,yyyymm);
     break;
    case 22:
     //1-4號既要判斷上月的,又要判斷本月的
     if(daysnumber <= 4){
      //上個月執行完就執行昨天的,中間幾天不用判斷,因為是月表
      if(d > beginday){
       d = endday -1;
      }
     }
    
     //增加月份字尾
     gettime_yyyymm(yyyymm,d);
     strcat(tablelist[t].tblnameNew,yyyymm);
     break;
    case 3:
     gettime_yyyymmdd(yyyymmdd,d);
     strcat(tablelist[t].tblnameNew,yyyymmdd);
     break;
    case 33:
     gettime_yyyymmdd(yyyymmdd,d);
     strcat(tablelist[t].tblnameNew,yyyymmdd);
     break;    
   }
   
   //SELECT create_time
   //FROM TABLES
   //WHERE TABLE_SCHEMA = 'v_9999' AND
   //table_name = 'e_customer'
   strcpy(SQL,"SELECT create_time\n"
         "FROM TABLES\n"
         "WHERE TABLE_SCHEMA = \'vos_");
   strcat(SQL,PlatFormID);
   strcat(SQL,"\' AND\n");
   strcat(SQL,"table_name = \'");
   strcat(SQL,tablelist[t].tblnameNew);  
   strcat(SQL,"' AND\n");
   
   //不同型別的表需要動態新增字尾,比如20150601
   switch(tablelist[t].type){
    case 1:
     strcat(SQL,"create_time > CURRENT_DATE()");
     break;
    case 2:
     strcat(SQL,"1 = 1");  //日表只需要判斷是否存在,不需要判斷日期
     break;
    case 3:
     strcat(SQL,"1 = 1");  //日表只需要判斷是否存在,不需要判斷日期
     break;
    case 33:
     strcat(SQL,"1 = 1");  //日表只需要判斷是否存在,不需要判斷日期
     break;   
    case 11:
     strcat(SQL,"create_time > \'");
     gettime_yyyy_mm_dd(yyyy_mm_dd, -1);
     strcat(SQL,yyyy_mm_dd);
     strcat(SQL," 21:00:00.001\'");
     break;
    case 22:
     strcat(SQL,"create_time > date_add(CURRENT_DATE(),interval ");
     memset(dt_tmp,0,sizeof(dt_tmp));
     sprintf(dt_tmp,"%d",d +1);
     strcat(SQL,dt_tmp);
     strcat(SQL," day)");
     break;        
   } 
   
   printf("執行SQL:-----------------------[表 %d: %s]---[第 %d 天]-----------------------\n",
        t,tablelist[t].tblnameNew,d);  
   printf(tablelist[t].tblnamePre);
   printf("\n"); 
   
   printf(SQL);
   printf("\n\n");
   
   res=mysql_query(&my_conn_schema,SQL);//查詢 
   if(res != 0){
    printf(">>>>>>>>res=mysql_query(&my_conn_schema,SQL<判斷表是否存在>) 時失敗: res = %d\n",res);
    return -1;
   }
   
   result=mysql_store_result(&my_conn_schema);//儲存查詢到的資料到result 
   if((unsigned long)mysql_num_rows(result)>0){ 
    printf("已經同步了這個表 [跳過]++++++++++++++++\n\n");
    continue;
   }
  
    //需要匯出的
   printf("尚未同步這個表,加入到mysqldump列表中去++++++++++++++++\n");
   
   //匯出檔名
   char ExportFile[255];
   strcpy(ExportFile,SourcePath);
   strcat(ExportFile,tablelist[t].tblnamePre);
   strcat(ExportFile,".sql");
   
   //注意本地mysql沒有密碼,所以mysqldump不需要加什麼密碼等引數
   strcpy(MyDump,"mysqldump v9999 ");
   strcat(MyDump,tablelist[t].tblnameNew);
   strcat(MyDump," --skip-comments");
   
   
   strcat(MyDump,">");
   strcat(MyDump,ExportFile);
   
   //執行
   printf("執行匯出命令: %s\n",MyDump);
   //刪除檔案先
   remove(ExportFile);
   system(MyDump);
   
   //如果命令列有錯誤,仍然生成空檔案,所以判斷檔案是否寫成功  
   if(get_filesize(ExportFile)<= MIN_FILESIZE){
    printf("匯出出現異常,跳過該表的匯入++++++++++++++++\n\n");
    continue;
   }  
   
   //連線到平臺數據庫,匯入
   //格式: mysql -u root -p123456 test <d:\a.sql
   strcpy(MyImport,"mysql -h");
   strcat(MyImport,IP);
   strcat(MyImport," -P");
   strcat(MyImport,Port);
   strcat(MyImport," -u");
   strcat(MyImport,User);
   strcat(MyImport," -p");
   strcat(MyImport,Pwd);
   strcat(MyImport," ");
   strcat(MyImport,DB_PLATFORM);
   strcat(MyImport," < ");
   strcat(MyImport,ExportFile);
   
   printf(MyImport);
   printf("\n");
   
   //執行
   system(MyImport);
   printf("\n");
  } //for d
 }//for t
 
 mysql_free_result(result);//釋放結果資源 
 mysql_close(&my_conn_schema);//斷開連線

 //結束提示
 printf("已經結束全部的處理過程++++++++++++++++++++++++++++++++\n\n\n");
 
  //main結束
  exit(0);
}



相關推薦

第一使用linux編寫一個dump mysql程式記錄簡單步驟

機器安裝linux redhat5.0 64位。客戶管理員給了我賬戶密碼,我用SecureCRT登入。 連線後: ls  列表檔案,當然支援萬用字元 cd path 進入某個目錄   *SecureCRT中可以像window一樣複製路徑,比較方便。 cd .. 返回上層 c

C語言入門 2 安裝VS2013開發環境編寫一個C語言程式

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C語言入門 2 安裝VS2013開發環境編寫一個C語言程式

                在C語言入門系列中,我們使用Visual studio 2013 Professional作為開發工具。本篇詳細介紹如何安裝Visualstudio 2013 Professional並寫出我們第一個C程式。1、工具準備開發機環境:Win7或以上版本作業系統,Internet

這周擼兩款小程式分享小經驗。

本週擼了兩款小程式,在這裡總結下開發過程中的小經驗,希望對大家有用。 小程式端 我們先說小程式要注意的地方。 ##預設入口轉發問題 當一個小程式Page的js檔案中存在 onShareAppMessage 方法時,可以觸發轉發功能,但是通過小程式開發者工具生

近期處理多個Highcharts圖標時碰到重復操作所以編寫一個流程控制器

null sql 控制 lin end created 格式 har 合並數組 HTML選擇頁面 第一部分:<?php /** * Created by PhpStorm. * User: Administrator * Date: 2018/9/8 * Tim

第一安卓作業(一個北京天氣預報)

第一次安卓作業(一個北京天氣預報) 有待修正與完善 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/andr

編寫一個自動從編碼log中提取資料的程式

筆者這半年來一直是自己手動將編碼後的資料一個一個敲到excel中的,真是笨的可以,今天終於下定決心寫個小程式。 首先感謝下面的博主: https://blog.csdn.net/sruru/article/details/7911675 告訴了我怎麼在main函式傳入引數 ht

第一初學爬蟲編寫的最簡單的爬出百度貼吧的圖片

、`此程式碼可以無限翻頁下載,可以在上面直接改URL裡面的貼吧名字就能爬取自己喜歡的貼吧的圖片,不過 不建議爬取大貼吧,因為大貼吧 帖子多 執行很久才能下載,下面附上簡單的程式碼 url=‘https://tieba.baidu.com/f?kw=效能測試&am

EJB環境配置(jboss-as-7.1.1+jdk1.8+eclipse)編寫一個EJB程式

文章目錄 一、環境配置 寫在前面 下載jboss-as-7.1.1.final並配置環境變數 如果你是jdk1.8,那麼安裝jdk1.7並修改standlone.bat 在eclipse中安裝JBoss Tools開發外掛

編寫一個Java 應用程式計算兩個大整數的和、差、積和商計算一個大整數的因 子個數(因子中不包括1 和大整數本身)。

1 package ex6_2; 2 import java.math.BigInteger; 3 4 public class BigintegerExample { 5 public static void main(String[] args) { 6

編寫一個Java 應用程式使用者從輸入對話方塊輸入兩個日期程式將判斷兩個日期的 大小關係以及兩個日期之間的間隔天數。

1 package ex6_1; 2 3 import java.sql.Date; 4 import java.util.Calendar; 5 6 import javax.swing.JOptionPane; 7 8 public class DateExample { 9

ubuntu編寫執行第一個c語言程式

對於初入Ubantu系統的小夥伴來說,進入Ubuntu最想做的事莫過於在終端(Terminal)裡執行自己的第一個C/C++程式"hello.c/hello.cpp"了。 Ubuntu預設是不包含編輯器vim和編譯器gcc。如果你是剛安裝好的Ubuntu電腦,下面我們將

第一章 編寫一個angular應用程式

一個簡單的reddit應用程式 在這一章,我們編寫一個能夠提交一篇文章(包含URL以及標題)並且可以對帖子進行投票的應用程式。 你可以認為這個應用程式是Reddit.com或者Product Hunt的原型。 在這個簡單的應用程式中,我們將會學習到an

PyCharm入門第一步-——建立執行第一個Python專案

建立專案 點選Create New Project 建立專案 輸入自己的專案名,點選Create建立   建立檔案  右鍵專案名建立python檔案 建立一個HelloPython檔案 輸入print("Hello word") 右鍵空白地方測試執行 &n

在Android中如何獲取視訊的第一幀圖片顯示在一個ImageView中

String path  = Environment.getExternalStorageDirectory().getPath();MediaMetadataRetriever media = new MediaMetadataRetriever();media.setD

編寫一個HTTP高匿代理

本以為編寫http代理和上一篇的埠轉發差不多的,結果實際一編寫起來發現要複雜的多。怎麼回事呢,就在於要手動解析http協議。 說簡單點吧,如果直接用ie上一個網站,用sniffe一看http請求頭是這樣的。 GET / HTTP/1.1Accept: application

我發起創立一個 Javascript 前端庫 開源項目 jWebForm

web image mage dynamic mic bsp 創建 eat 引用 我發起並創立了一個 Javascript 前端庫 開源項目 jWebForm 。 起因是我前幾天寫了一篇文章《.Net Core 沒有 WebForm 是 歷史 的 退步》, 然後有

我發起創立一個 VMBC 的 子項目 D#

需要 也會 編譯 大小 裏的 沒有 實現 固態硬盤 基礎架構 大家好, 我發起並創立了一個 VMBC 的 子項目 D# 。 有關 VMBC , 請參考 《我發起了一個 用 C 語言 作為 中間語言 的 編譯器 項目 VMBC》 https://www.cnb

我發起創立一個 C 語言編譯器 開源項目 InnerC

語法 inner href 一點 類型 語言 ilb com htm 本文是 VMBC / D# 項目 的 系列文章, 有關 VMBC / D# , 見 《我發起並創立了一個 VMBC 的 子項目 D#》(以下簡稱 《D#》) https://www.cnblogs.