• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 200, comments - 8, trackbacks - 0, articles - 0

            linux高級編程day04 筆記(轉)

            Posted on 2012-12-31 15:30 鑫龍 閱讀(743) 評論(0)  編輯 收藏 引用 所屬分類: 楊強linux視頻筆記系列

            一.IO與文件映射
             1.IO的共享與效率
              read與write其中數據緩沖的大小
              讀取數據的緩沖大小:getpagesize。 
             2.定位與定位讀取(隨機讀取)
              read與write在操作的時候,自動移動讀取位置.
              lseek改變讀取位置.

              pread/pwrite在指定位置讀寫。
              2.1.lseek的函數說明: 

             off_t   lseek(
                                int fd,//定位文件描述符號
                                off_t off,//定位位置
                                int whence//定位參照點:文件開始位置/文件結束位置/文件當前位置
                                                    
            //SEEK_SET    SEEK_END  SEEK_CUR
                                );
             返回:
                   返回當前讀取位置在文件中的絕對位置.
              2.2.lseek的作用:定位文件的位置
                問題:lseek的定位的位置超出文件的大小范圍?
                lseek移動位置只要合法,都是有效
              2.3.lseek+write=pwrite
                  lseek+read =pread

            #include <stdio.h>
            #include <fcntl.h>
            #include <stdlib.h>
            main()
            {
                int fd;
                float score;
                int r;
                int i=0;
                fd=open("stu.dat",O_RDWR);
                if(fd==-1) printf("open error:%m\n"),exit(-1);
                    
                //定位
                /*
                for(i=0;i<2;i++)
                {
                    r=lseek(fd,i*28,SEEK_SET);    
                    r=lseek(fd,24,SEEK_CUR); 
                    //r=lseek(fd,i*28+24,SEEK_SET);
                    //讀取
                    r=read(fd,&score,sizeof(float));
                    //打印 輸出
                    printf("%.2f\n",score);
                }
            */
                /*
                r=lseek(fd,-100,SEEK_SET);
                printf("%d\n",r);
                //write(fd,"Hello",5);
                
            */
                for(i=0;i<2;i++)
                {
                    pread(fd,&score,sizeof(float),i*28+24);
                    printf("%.2f\n",score);
                    read(fd,&score,sizeof(float));
                    printf("%.2f\n",score);
                }
                
                close(fd);
            }
            2.4.案例:
                 讀取一個特殊的文件:
                   /proc/${pid}/mem文件程序的虛擬內存文件

            #include <stdio.h>
            #include <stdlib.h> 
            #include <fcntl.h>
            int a=9999;
            main()
            {
                char filename[100];
                int fd;
                int data=8888;
                
                //得到文件名
                sprintf(filename,"/proc/%d/mem",getpid());
                //打開文件
                fd=open(filename,O_RDWR);
                if(fd==-1) printf("open error:%m\n"),exit(-1);
                //讀取a地址這個位置的數據
                
            //pread(fd,&data,4,(int)&a);
                
            //lseek(fd,(int)&a,SEEK_SET);
                
            //read(fd,&data,4);
                
            //write(fd,&data,4);
                pwrite(fd,&data,4,(int)&a);
                printf("%d\n",a);
                
                close(fd);
            }
            3.文件的其他操作
                fstat獲取文件狀態
                ftruncate改變文件大小

            #include <fcntl.h>
            #include <stdio.h>
            #include <stdlib.h>
            #include <unistd.h>
            #include <sys/stat.h>
            main()
            {
                int fd;
                struct stat st;
                
                fd=open("stu.dat",O_RDONLY);
                if(fd==-1) printf("err:%m\n"),exit(-1);
                
                fstat(fd,&st);
                printf("%d,%o\n",st.st_size,st.st_mode);
                
                close(fd);
            }
            4.文件映射:
                虛擬地址映射到內存。
                虛擬地址可以映射到文件:可以用內存方式訪問文件.
                mmap/munmap
              案例:
                1.使用內存方式寫入數據 

            #include <stdio.h>
            #include <stdlib.h>
            #include <unistd.h>
            #include <fcntl.h>
            #include <sys/stat.h>
            #include <string.h>
            #include <sys/mman.h>
            struct stu
            {
                char name[20];
                int  age;
                float score;
            };
            main()
            {
                int fd;
                struct stu *s;//文件在虛擬內存的映射首地址
                struct stat st;
                int size;//文件大小
                int count;//記錄條數
                int i;
                //1.打開文件
                fd=open("newstu.dat",O_RDWR|O_CREAT|O_EXCL,0666);
                if(fd==-1)
                {
                    fd=open("newstu.dat",O_RDWR);
                    if(fd==-1) printf("::%m\n"),exit(-1);
                }
                //2.得到文件大小,文件記錄條數
                fstat(fd,&st);
                size=st.st_size;
                count=size/sizeof(struct stu);
                //3.文件大小改變只要在munmap之前調用都有效    
                
            //ftruncate(fd,size+sizeof(struct stu));
                
            //4.映射到一個虛擬的地址
                s=mmap(0,size+sizeof(struct stu),
                            PROT_READ|PROT_WRITE,
                            MAP_SHARED,fd,0);
                //5.把數據寫入虛擬地址
                /*
                printf("輸入姓名:");
                scanf("%s",s[count].name);
                printf("輸入年齡:");
                scanf("%d",&(s[count].age));
                printf("輸入成績:");
                scanf("%f",&(s[count].score));
                ftruncate(fd,size+sizeof(struct stu));
                
            */
                for(i=0;i<count;i++)
                {
                    printf("%s,\t,%d,\t%.2f\n",
                        s[i].name,s[i].age,s[i].score);
                }    
                //6.卸載虛擬地址
                munmap(s,sizeof(struct stu)+size);
                //7.關閉文件
                close(fd);
            }

            作業:
              -+
            2.使用內存方式讀取數據
             
            二.文件描述符號的操作(IO鎖)
              文件描述符號是整數.文件描述符號對應內核的上下文環境. 
              1.dup  dup2拷貝文件描述符號
               dup拷貝文件符號,返回系統指定的整數
               dup2拷貝文件描述符號,返回用戶指定的整數
              2.fcntl對文件描述的屬性的修改
                2.1.拷貝文件描述符號
                2.2.修改判定文件的描述標記
                2.3.修改判定文件的狀態標記
                     O_RDONLY O_WRONLY _ORDWR  O_CREAT O_EXCL
                     
                     O_APPEND O_ASYN
                2.4.設置強制鎖(重新編譯內核)
                2.5.設置建議鎖(默認)
                2.6.設置的信號 

            三.IO與Curses(介紹)
              Curses:CUI
              
              UI:User Interface.
               CUI:字符界面
               GUI:圖形界面
             
             使用一套封裝庫  libcurses.so
             /usr/lib目錄下
             
             編譯只需要指定-lcurses
             老版本:libcurses.so
             新的版本:libncurses.so
             如果頭文件curses.h不存在,請嘗試使用ncurses.h
             如果庫curses不存在,嘗試使用ncurses
             
             printf /scanf標準IO
             大部分標準IO重定向到終端./dev/tty  /dev/pts/1
             
             curses就是終端輸出.
             -lcurses   -ncurses 
             
             為了防止printf重定向到終端破壞UI,禁止在curses中使用標準IO.
             
             
             1.編程模型
               初始化終端initscr
               操作終端(輸入/輸出/定位/刷新....)
               釋放終端endwin
             2.顯示
               2.1.圖形輸出
                border    
                box    
                hline    
                vline

            #include <curses.h>
            int main()
            {
                initscr();//初始化終端
                
            //border(0,0,0,0,0,0,0,0);
                box(stdscr,0,0);
                mvhline(2,10,'=',20);
                mvvline(2,10,'|',10);
                refresh();
                //wrefrsh(stdscr);
                getch();//等待一個字符輸入        
                endwin();//釋放終端
                return 0;
            }
            屬性字符:字節=屬性字節+字符字節
               注意:
                 box需要窗體.
                 initscr返回被初始化的窗體:標準屏幕WINDOW*
                 實際上curses定義一個全局變量stdscr就是標準屏幕 
               函數命名規則:
                  ****   標準屏幕stdscr
                  w****    指定窗體
                  mv****  指定位置
                  mvw****  指定窗體的指定位置
               2.2.刷屏
                 void refresh()   
                 void wrefresh(WINDOW*);
                 
                 從里到外刷屏
               2.3.字符輸出
                 addch
                 普通字符:''
                 屬性字符: '' | 屬性 //位與,屬性可以man attron查看可選屬性    
                 
                 特殊的屬性字符(特殊形狀):比如ACS_PI

               2.4.字符串輸出
                 int addstr(const char *);
               2.5.格式字符串輸出
                 int printw(const char*,....);  

            #include <curses.h> 
            main()
            {
                char name[9]={0};
                int r;
                initscr();
                //繪制UI
                mvaddstr(4,10,"用戶:[        ]");
                //輸入
                r=mvgetnstr(4,16,name,8);
                //name[r]=0;
                
            //打印輸入
                mvprintw(7,10,"你輸入的是:%s",name);
                refresh();
                //輸入字符    
                getch();
                endwin();
            }
            3.字符屬性與顏色
                顏色屬性
                3.1.判定終端是否支持顏色
                  bool has_colors();//都支持顏色,建議不判定
                3.2.初始化顏色:
                  int start_color();
                3.3.定義顏色對
                  int init_pair(short pair,short fore,short back);
                3.4.使用顏色對
                  COLOR_PAIR(short pair)      
                3.5.設置屬性
                  attron()開啟屬性
                  attroff()關閉屬性
                  括號里傳入所需要開啟或者關閉的屬性,      
                  如:attron(COLOR_PARE(1));//開啟顏色對1
                這組函數一定要在initscr后調用
                
                背景函數:
                  bkgd();
            #include <curses.h>
            #include <time.h>
            #include <unistd.h>
            void init();
            void drawui();
            void business();
            void destroy();
            main()
            {
                init();
                drawui();
                business();
                destroy();
            }
            void business()
            {
                time_t tt;
                struct tm *t;
                while(1)
                {
                    //取時間
                    tt=time(0);
                    t=localtime(&tt);
                    //顯示時間
                    mvprintw(LINES/2,(COLS-8)/2,
                        "%02d:%02d:%02d",
                        t->tm_hour,t->tm_min,t->tm_sec);
                    //刷新屏幕
                    refresh();
                    sleep(1);
                }
            }
            void drawui()
            {
                box(stdscr,0,0);
            }
            void destroy()
            {
                endwin();
            }
            void init()
            {
                initscr();
            }
             2.登錄界面
                 1.初始化
                 2.繪制界面
                    頭
                    繪制用戶名輸入區
                    繪制密碼輸入區
                    
                 3.等待輸入
                 4.結束
            #include <curses.h>
            #include <unistd.h>
            #include <stdlib.h>
            #include <string.h>
            void init();
            void drawLogin();
            void destroy();
            main()
            {
                init();
                drawLogin();
                destroy();
            }
            void drawLogin()
            {
                char *heads="聯通BSS業務支撐系統";
                char *user="用戶[           ]";
                char *pass="口令[           ]";
                
                box(stdscr,0,0);
                attron(A_BOLD);
                mvaddstr(3,(COLS-strlen(heads))/2,heads);
                mvhline(4,(COLS-strlen(heads))/2,0,strlen(heads));
                attroff(A_BOLD);
                mvaddstr(8,(COLS-strlen(user))/2,user);
                mvaddstr(10,(COLS-strlen(pass))/2,pass);
                refresh();
            }
            void destroy()
            {    
                getch();
                endwin();
                
            }
            void init()
            {
                initscr();
            }
            4.輸入
               1.字符輸入
                int getch();
                返回的是字符
                禁止回顯noecho() //回顯只是輸入以后不會出現在屏幕上,輸入密碼時采用這種方式
                使功能鍵有效,使用keypad(WINDOW*,bool) 

            #include <curses.h>
            main()
            {
                int ch;
                //初始化
                initscr();
                noecho();
                //循環輸入
                while(1)
                {
                    ch=mvgetch(5,10);
                    //循環顯示輸入
                    mvprintw(8,10,"你輸入的是:%c(%d)",ch,ch);
                }    
                //釋放
                endwin();
            }
            案例:
               使用鍵盤控制字母在屏幕上的移動
                
               補充:
                 curses屏幕清除:man 3 clear
                   clear
                   erase 
                 光標控制:
                   得到光標位置  getsyx
                   設置光標的位置 setsyx
                   控制光標是否可見:curs_set();
                   
               2.字符串輸入
                  int addstr
               
               3.格式數據輸入
                 scanw
            #include <curses.h>
            main()
            {
                int ch;
                int x=5,y=5;
                initscr();
                keypad(stdscr,TRUE);
                curs_set(0);
                noecho();
                mvaddch(y,x,'A');
                while(1)
                {
                    ch=getch();
                    //mvaddch(y,x,' ');
                    
            //clrtoeol();
                    erase();
                    //clear();
                    switch(ch)
                    {
                    case KEY_UP:
                        y--;
                        break;
                    case KEY_DOWN:
                        y++;
                        break;
                    case KEY_LEFT:
                        x--;
                        break;
                    case KEY_RIGHT:
                        x++;
                        break;
                    }
                    mvaddch(y,x,'A');
                    refresh();
                }        
                endwin();
            }
            5.窗口 
               subwin()//創建子窗體(坐標采用標準屏幕坐標)
               derwin()//創建子窗體(坐標采用父窗體坐標)

            #include <curses.h>
            main()
            {
                WINDOW *w;
                initscr();
                box(stdscr,0,0);
                
                w=derwin(stdscr,4,20,5,3);
                box(w,0,0);
                
                refresh();
                wrefresh(w);
                getch();
                endwin();
            }

            #include <curses.h>
            void init();
            void drawUi();
            void dealInput();
            void destroy();
            main()
            {
                init();
                drawUi();
                dealInput(); 
                destroy();
            }
            void dealInput()
            {
                int a,b;
                while(1)
                {
                    mvaddstr(2,3,"     ");
                    mvscanw(2,3,"%d",&a);
                    mvaddstr(2,11,"     ");
                    mvscanw(2,11,"%d",&b);
                    mvaddstr(2,19,"      ");
                    mvprintw(2,19,"%d",a+b);
                    refresh();
                }
            }
            void drawUi()
            {
                mvaddstr(2,2,"[     ]+[     ]=[      ]");
                refresh();
            }
            void destroy()
            {
                endwin();
            }
            void init()
            {
                initscr();
            }
            1.在vi設置編碼:
              :set encoding=編碼    gb2312  ios-8859-1  utf-8 
            2.在編譯器指定源文件的編碼 -finput-charset=gb2312
            3.在終端指定編碼:
            4.系統默認編碼
              /etc/sysconfig/i18n配置編碼
              
                  
            作業:(使用文件映射) 
             1.使用內存方式讀取數據
             2.使用curses+io完成:圖書信息的錄入
             3.使用curses+io顯示圖書信息:
                每次顯示一條:
                使用up down鍵翻滾記錄數據
             4.讀取文件文件,使用curses 顯示.
                實現如下功能:
                   上下翻頁功能
                   輸入q,結束功能 

             

            久久久精品一区二区三区| 久久亚洲AV成人无码| 99re这里只有精品热久久| 国内精品伊人久久久久av一坑| 亚洲一本综合久久| 久久久久av无码免费网| 国产精品久久波多野结衣| 国产综合免费精品久久久| 久久亚洲国产成人影院网站| 99精品国产99久久久久久97| 青青草原1769久久免费播放| 婷婷国产天堂久久综合五月| 韩国三级大全久久网站| 热久久最新网站获取| 久久99精品国产一区二区三区| 婷婷久久综合| 国产精品亚洲综合专区片高清久久久 | 精品久久人妻av中文字幕| 国产高潮国产高潮久久久91 | 久久久久18| 亚洲国产另类久久久精品小说| 久久精品国产精品国产精品污 | 久久国产免费观看精品| 77777亚洲午夜久久多喷| 精品人妻伦一二三区久久| 久久夜色精品国产欧美乱| 久久亚洲天堂| 久久久久免费视频| 久久成人国产精品一区二区| 精品国产乱码久久久久久郑州公司| 久久精品人人做人人爽电影| 欧美久久久久久| 色婷婷综合久久久久中文字幕| 久久福利片| 久久精品成人免费国产片小草 | 一本伊大人香蕉久久网手机| 97久久精品午夜一区二区| 久久久久久狠狠丁香| AA级片免费看视频久久| 国产精品成人久久久久久久| 久久久噜噜噜久久|