亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

【C語(yǔ)言有什么用?①】從零開(kāi)始擼一個(gè)用戶(hù)態(tài)模擬文件系統(tǒng)

不知名網(wǎng)友 / 3576人閱讀

摘要:返回值是文件描述符,表示在文件打卡表項(xiàng)的位置在內(nèi)存中,保存著打開(kāi)文件的位置信息,是系統(tǒng)為我們維護(hù)的方便使用的一個(gè)符號(hào)。這張圖就是一個(gè)最簡(jiǎn)單的文件系統(tǒng),但是作業(yè)要求我們有和數(shù)據(jù)塊的分配回收,所以我們得加上位示圖和數(shù)據(jù)塊的位示圖。

?寫(xiě)在前面?
學(xué)習(xí)一個(gè)語(yǔ)言最好的方法是做一個(gè)小項(xiàng)目,這個(gè)項(xiàng)目不需要多么復(fù)雜,但是一定能激發(fā)你的學(xué)習(xí)興趣。讓我們?cè)挷欢嗾f(shuō),開(kāi)始吧

本文將帶你手?jǐn)]一個(gè)磁盤(pán)組織方式的模擬,你將學(xué)到

  • ? c語(yǔ)言指針的使用
  • ? linux的系統(tǒng)調(diào)用
  • ? 磁盤(pán)的組織方式?
  • ? 超級(jí)塊存儲(chǔ)哪些信息?
  • ? inode存儲(chǔ)哪些內(nèi)容?
  • ? 位示圖有啥用?

全文大約閱讀時(shí)間: 30min

??作者簡(jiǎn)介:一個(gè)從工業(yè)設(shè)計(jì)改行學(xué)嵌入式的年輕人
?資源下載:gitee倉(cāng)庫(kù)
?聯(lián)系方式:2201891280(QQ)


一、基本要求介紹

?目標(biāo)

完成用戶(hù)態(tài)環(huán)境下的磁盤(pán)模擬功能,提供磁盤(pán)基本信息查詢(xún)與格式化功能。

?形式要求

基于C/C++,完成上述完整功能

?實(shí)現(xiàn)約束

利用一個(gè)大文件(128MB)來(lái)模擬磁盤(pán)塊設(shè)備,基于固定分片大小實(shí)現(xiàn)文件系統(tǒng)的超級(jí)塊區(qū)、inode節(jié)點(diǎn)區(qū)、數(shù)據(jù)分片區(qū)的管理,具備磁盤(pán)格式化、文件系統(tǒng)查詢(xún)(如:fdisk -l)功能,支持文件的inode節(jié)點(diǎn)和對(duì)應(yīng)數(shù)據(jù)分片的分配、回收。

注:此為樓主的一次linux作業(yè),鑒于還沒(méi)到提交作業(yè)的截至日期,所以如果你 借鑒 此篇文章,請(qǐng)修改一定量以防大家都沒(méi)分?jǐn)?shù)0.0


二、解決方法思路

拿到一道要求時(shí),最重要的是學(xué)會(huì)找資源,找到一些思路,然后自己去做實(shí)現(xiàn)。
所以我平時(shí)很喜歡問(wèn)思路的同學(xué),但是知道思路還不知道代碼怎么寫(xiě)呢,我就覺(jué)得這是態(tài)度問(wèn)題了,希望大家還是只借鑒思路,千萬(wàn)別直接復(fù)制粘貼,這對(duì)自己一點(diǎn)好處都沒(méi)有

?參考文章

  1. 文件系統(tǒng)簡(jiǎn)單模擬
    這篇文章實(shí)現(xiàn)的功能非常復(fù)雜,所以我只是借鑒了主程序的寫(xiě)法,主要是給自己做一個(gè)主程序的基礎(chǔ)架構(gòu)。

  2. ext2文件系統(tǒng)詳解
    這篇文件非常詳細(xì)的介紹了ext2文件系統(tǒng)的實(shí)現(xiàn)方式,這是已有的真實(shí)文件系統(tǒng)的結(jié)構(gòu),我們可以對(duì)其進(jìn)行適當(dāng)?shù)木?jiǎn),做出我們的想要的功能。

?主體實(shí)現(xiàn)思路

  • 模塊框架設(shè)計(jì)
  • 分片大?。?KB 則一共有32K(128M/4K)個(gè)分片
  • 保留區(qū):三個(gè)分片,分別為超級(jí)塊,inode位示圖,數(shù)據(jù)區(qū)位示圖
  • inode節(jié)點(diǎn):128B,每個(gè)分片有32個(gè)inode節(jié)點(diǎn),32K個(gè)分片需要1K個(gè)分片保存inode節(jié)點(diǎn)信息,分配inode節(jié)點(diǎn)區(qū)為4MB。

對(duì)應(yīng)的分配方式如下圖

  • 主程序設(shè)計(jì)

做一個(gè)類(lèi)似于終端的執(zhí)行方式,輸入相應(yīng)的命令執(zhí)行相應(yīng)的操作。
基本的效果如下


三、linux系統(tǒng)調(diào)用簡(jiǎn)介

為了細(xì)化上面提到一些細(xì)節(jié)實(shí)現(xiàn),我們需要了解linux的對(duì)文件的系統(tǒng)調(diào)用。這部分有點(diǎn)枯燥,畢竟都是系統(tǒng)調(diào)用函數(shù),但是也不多,熟悉這部分的同學(xué)直接跳過(guò)啦0.0

?open & close

int open (const char *name, int flags, mode_t mode);int close(int fd);

上面對(duì)應(yīng)的就是打開(kāi)和open和close系統(tǒng)函數(shù)定義

其中open有三個(gè)傳入?yún)?shù)

  • 第一個(gè)就很好理解就是文件名稱(chēng)
  • 第二個(gè)是flags表示打開(kāi)方式,這次用到的只有三個(gè) O_CREAT、O_WRONLY、
    O_RDONLY分別表示如果不存在就創(chuàng)建,只讀和只寫(xiě)。其中如果我想獲取讀寫(xiě)權(quán)限可以用 O_WRONLY|O_RDONLY 來(lái)表示。
  • 第三個(gè)參數(shù)我是再第二個(gè)參數(shù)有O_CREAT時(shí)候使用,是定義文件的權(quán)限的。因?yàn)槭菫榱藢W(xué)習(xí),我就簡(jiǎn)單的定義的所有人可讀可寫(xiě)可執(zhí)行S_IRWXO|S_IRWXG|S_IRWXU。
  • 返回值是文件描述符,表示在文件打卡表項(xiàng)的位置(在內(nèi)存中,保存著打開(kāi)文件的位置信息),是系統(tǒng)為我們維護(hù)的方便使用的一個(gè)符號(hào)。如果返回-1表示打開(kāi)失敗

相對(duì)來(lái)說(shuō)close就簡(jiǎn)單很多

  • 只有一個(gè)傳入?yún)?shù) 就是open的返回值文件描述符,是一個(gè)大于等于0的整數(shù)可以看下圖

?write & read

size_t read(int fd, void *buf, size_t count);size_t write(int filedes,const char* buf,size_t nbytes);

這兩個(gè)函數(shù)很類(lèi)似,只不過(guò)功能一個(gè)是讀一個(gè)是寫(xiě),我就放在一起講了。都有三個(gè)參數(shù)

  • 第一個(gè)參數(shù)是一個(gè)文件打開(kāi)表項(xiàng),其實(shí)就是我們剛才說(shuō)的open返回值。
  • 第二個(gè)是一個(gè)指針,如果忽略他的類(lèi)型可以理解為一片內(nèi)存空間,其中read就是往這片空間寫(xiě)入數(shù)據(jù),wirte就是將對(duì)應(yīng)的空間的數(shù)據(jù)寫(xiě)入文件。
  • 第三個(gè)數(shù)據(jù)是讀或者寫(xiě)的數(shù)據(jù)大小,單位是字節(jié)。千萬(wàn)別超過(guò)第二個(gè)參數(shù)中指針指向的數(shù)據(jù)大小,不然會(huì)寫(xiě)入未知內(nèi)存,造成程序未知錯(cuò)誤,建議直接就sizeof(第二個(gè)元素)

這兩個(gè)函數(shù)可以說(shuō)對(duì)于c語(yǔ)言指針的使用極度舒適,直接操作內(nèi)存。
需要注意一個(gè)點(diǎn)就是每次讀寫(xiě)系統(tǒng)會(huì)將我們的文件偏移量往后推移讀到元素個(gè)數(shù)

?lseek

#include #include off_t lseek(int fd, off_t offset, int whence);

上面說(shuō)到每次read和wirte都會(huì)推進(jìn)文件偏移量。所以為了改變文件偏移量,我們就有了這個(gè)函數(shù)。

  • 第一個(gè)參數(shù)還是文件打開(kāi)表項(xiàng),就是open返回那個(gè)
  • 第二個(gè)參數(shù)就是偏移量。單位是字節(jié),可前可后,所以就可以正也可以負(fù)值。
  • 第三個(gè)參數(shù)是相哪里的位置 有三個(gè)可選項(xiàng)SEEK_SET、SEEK_CUR、SEEK_END,分別表示相對(duì)文件頭、相對(duì)當(dāng)前位置以及相對(duì)文件末尾。我們只需要前兩個(gè)就好了。

上面就是所有需要的基本系統(tǒng)調(diào)用函數(shù),接下來(lái)介紹一些燒腦的文件結(jié)構(gòu)。


四、磁盤(pán)組織方式簡(jiǎn)介


圖片是一個(gè)常見(jiàn)的文件系統(tǒng)的圖片,我們需要實(shí)現(xiàn)的只有單分區(qū)就好了,不那么復(fù)雜。

這張圖就是一個(gè)最簡(jiǎn)單的文件系統(tǒng),但是作業(yè)要求我們有inode和數(shù)據(jù)塊的分配回收,所以我們得加上inode位示圖和數(shù)據(jù)塊的位示圖。

文件訪問(wèn)的過(guò)程

當(dāng)我們嘗試訪問(wèn)一個(gè)文件/123/456.txt的時(shí)候基本過(guò)程是

從這個(gè)過(guò)程中我們知道

  • 超級(jí)塊(一般是第一塊)
    主要保存文件系統(tǒng)的基本信息,數(shù)據(jù)分片的大小、inode節(jié)點(diǎn)大小和多少,根目錄的位置等
  • inode節(jié)點(diǎn)
    **文件的基本信息,**文件大小、文件類(lèi)型、數(shù)據(jù)塊索引
  • 目錄項(xiàng)
    保存目錄信息 主要內(nèi)容是 文件名、inode節(jié)點(diǎn)號(hào)

五、主函數(shù)實(shí)現(xiàn)

主函數(shù)主要是為了打開(kāi)文件系統(tǒng)以及給一定的提示信息。

提示信息的輸出

void help(){    printf("****************************************************/n");    printf("*歡迎來(lái)到xinglei 的文件系統(tǒng)!??!                   /n");    printf("*主要的功能介紹                                     /n");    printf("*    0.創(chuàng)建系統(tǒng)  :create_filesystem                 /n");    printf("*    1.格式化    :init                              /n");    printf("*    2.低級(jí)格式化:low_init                          /n");        printf("*    3.查看信息  :info                              /n");       printf("*    4.創(chuàng)建文件  :mkfile                            /n");    printf("*    5.查看位示圖:weishitu                          /n");    printf("*    6.刪除文件  :delfile                           /n");    printf("*    8.幫助信息  :help                              /n");    printf("*    9.顯示文件  :ls                                /n");       printf("*    10.退出     :quit                              /n");     printf("****************************************************/n");}

主要就是打印一些提示信息,方便用戶(hù)使用這個(gè)系統(tǒng)。

類(lèi)終端功能實(shí)現(xiàn)

char* command[] = {"create_filesystem","init","low_init","info","mkfile","weishitu","delfile","deldir","help","ls","quit"};int commandnum = sizeof(command)/sizeof(char *);char path[100] = "file_system";//文件系統(tǒng)while(1){        printf("%s$ ",path);        scanf("%s",com);        choice = i;        for(i=0; i<commandnum; ++i)                    if(strcmp(com,command[i])==0)                        break;        choice = i;        if(Disk == -1 && (!(choice == 0|| choice == 10))){//未創(chuàng)建文件只能退出或者創(chuàng)建文件            printf("文件系統(tǒng)未創(chuàng)建,請(qǐng)創(chuàng)建文件系統(tǒng)。");            continue;        }        int a;        read(Disk,&a,sizeof(int));        if(Disk != -1 &&a == 0 && !(choice == 1 || choice == 2)){            printf("未格式化,請(qǐng)格式化.");            lseek(Disk,-sizeof(int),SEEK_CUR);            continue;        }        lseek(Disk,-sizeof(int),SEEK_CUR);        switch(choice){            case 0://創(chuàng)建系統(tǒng)                create_filesystem();                break;            case 1://格式化                init(1);                break;            case 2://低級(jí)格式化                low_init();                break;            case 3://查看信息                info();                break;            case 4://創(chuàng)建文件                printf("輸入你要?jiǎng)?chuàng)建的文件名: ");                char filename[20];                scanf("%s",filename);                create_file(filename);                break;            case 5://查看位示圖                weishi();                break;            case 6://刪除文件                printf("請(qǐng)輸入你要?jiǎng)h除的文件:");                char delname[20];                scanf("%s",delname);                delfile(delname);                break;            case 8://幫助信息                help();                break;            case 9://顯示文件                ls();                break;            case 10:    //退出系統(tǒng)                quit = 1;                break;            default:                printf("%s command not found/n",com);        }

很顯然,我定義了一個(gè)while1,然后根據(jù)輸入命令的比較結(jié)果來(lái)選擇執(zhí)行哪個(gè)分支,默認(rèn)就是重新回到開(kāi)頭。在程序運(yùn)行的時(shí)候我已經(jīng)做了打開(kāi)文件的操作,因?yàn)槲业诔?jí)塊的前4個(gè)字節(jié)的數(shù)據(jù)是固定的不為0,所以我可以用它來(lái)判斷是否已經(jīng)格式化,然后其它的就是跳轉(zhuǎn)到相應(yīng)的功能中就好了0.0

這只是基礎(chǔ)程序框架,我們其它功能使用另外一個(gè)文件來(lái)實(shí)現(xiàn)


六、文件功能定義

上面我們已經(jīng)實(shí)現(xiàn)了基礎(chǔ)的程序功能,這部分我們要深入細(xì)節(jié),完成每一個(gè)小功能的實(shí)現(xiàn)。

主要數(shù)據(jù)結(jié)構(gòu)


?超級(jí)塊
就是像剛才說(shuō)的保存基礎(chǔ)信息

typedef struct{    int inodes_count,   blocks_count;               //超級(jí)塊和indoe總數(shù)    int free_inodes_count,  free_blocks_count;          //未使用block和inode量    short block_size,   inode_size;             //block和indoe大小 B    int first_data_block,   first_inode_block;          //第一塊數(shù)據(jù)塊第一塊inode節(jié)點(diǎn)位置    int inode_wei,      block_wei;              //位示圖所在塊號(hào)    short inodes_per_block;                     //每片中的inode數(shù)目    short frag_size;                        //每片大小    int root_inode;                         //根節(jié)點(diǎn)inode號(hào)    int size;                           //總大小B}chao;      //超級(jí)塊定義

?inode節(jié)點(diǎn)
這應(yīng)該是最簡(jiǎn)陋的inode節(jié)點(diǎn)了把?

typedef struct{    int i_mode;     //文件類(lèi)型,1表示文件,0文件表示目錄項(xiàng)    int i_size;     //文件的大小單位為B    int i_blocks;       //文件所占?jí)K數(shù)     int i_block[15];    //索引節(jié)點(diǎn) 12個(gè)直接索引 1個(gè)一級(jí)索引 2個(gè)二級(jí)索引}inode;     //inode節(jié)點(diǎn)定義

?目錄項(xiàng)
目錄項(xiàng)不用特別復(fù)雜

typedef struct{    char name[28];    int inode;}mulu;      //目錄項(xiàng)定義

?位示圖
就簡(jiǎn)單的一個(gè)位就好了。

unsigned int weishitu[1024];//位示圖定義

創(chuàng)建文件系統(tǒng)


這個(gè)功能就很簡(jiǎn)單,就創(chuàng)建一個(gè)128MB的文件就好了。注意判斷是否已經(jīng)存在文件避免覆蓋。
我用了一個(gè)4K的數(shù)組循環(huán)32K次寫(xiě)入來(lái)達(dá)到128MB0.0

void create_filesystem(){    if(Disk != -1){        printf("已經(jīng)存在文件系統(tǒng)/n");        return;    }    Disk = open(DISK,O_CREAT|O_WRONLY,S_IRWXO|S_IRWXG|S_IRWXU);    int a[1024] = {0};    for(int i = 0;i < 1<<15;i++) write(Disk,(void *)a,sizeof(a));//創(chuàng)建128MB文件    printf("創(chuàng)建文件系統(tǒng)成功/n");}

格式化


這部分就億點(diǎn)點(diǎn)復(fù)雜需要做的事情有一些多。
就是重寫(xiě)超級(jí)塊、重寫(xiě)位示圖、創(chuàng)建根節(jié)點(diǎn)信息。
代碼就不放了 因?yàn)樘L(zhǎng)了-.-
可以在倉(cāng)庫(kù)中找到,我相信你們看得懂

低級(jí)格式化


其實(shí)我們平時(shí)也有用到低級(jí)格式化,其實(shí)就將所有數(shù)據(jù)置為0。然后再執(zhí)行高級(jí)格式化就好了。

void low_init(){    int temp;    read(Disk,&temp,sizeof(int));    if(temp){        printf("此操作會(huì)清空磁盤(pán),且不可恢復(fù),確定?Y/N  ");        char s[10];        while(scanf("%s",s) != EOF && !(!strcmp(s,"Y") || !strcmp(s,"N")))            printf("請(qǐng)輸入正確的字符");        if(strcmp(s,"N") == 0){            printf("用戶(hù)取消/n");            return ;        }    }    close(Disk);    Disk = open(DISK,O_WRONLY);    int a[1024] = {0};    for(int i = 0;i < 1<<15;i++) write(Disk,a,sizeof(a));//全部位置置0    close(Disk);    Disk = open(DISK,O_RDONLY);    printf("低級(jí)格式化完成/n");    init(0);}

這里其實(shí)和創(chuàng)建文件很類(lèi)似,但是要注意判斷是否已有系統(tǒng)給與對(duì)應(yīng)提示。

創(chuàng)建文件


這里已經(jīng)簡(jiǎn)化了很多了,只做了創(chuàng)建文件,并不寫(xiě)入數(shù)據(jù),所以就是找空間分配空間,寫(xiě)入就好了。
但是要實(shí)現(xiàn)找inode節(jié)點(diǎn)、找數(shù)據(jù)節(jié)點(diǎn)等多個(gè)方法,所以請(qǐng)看源碼。。

刪除文件


相比較而言刪除文件就簡(jiǎn)單很多直接將inode和數(shù)據(jù)區(qū)進(jìn)行回收就好了。
好了,由于很多細(xì)節(jié)放代碼過(guò)于復(fù)雜今天就寫(xiě)到這里了。


七、寫(xiě)在最后

這只是這次作業(yè)的的一部分,有點(diǎn)難懂,而且做成的也只能在電腦上跑跑看而已,第二部分是一個(gè)多線(xiàn)程詞頻統(tǒng)計(jì)工具,可以對(duì)某個(gè)文件目錄所有英文單詞的出現(xiàn)頻率進(jìn)行統(tǒng)計(jì)打印,就有用很多。
如果點(diǎn)贊破百的話(huà),我交作業(yè)前(11.30)肯定能更新出來(lái)0.0
海報(bào)我都做好了-.-

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/125652.html

相關(guān)文章

  • 從零到一,一個(gè)在線(xiàn)斗地主(上篇)

    摘要:原文從零到一,擼一個(gè)在線(xiàn)斗地主上篇作者背景朋友來(lái)深圳玩,若說(shuō)到在深圳有什么好玩的,那當(dāng)然是宅在家里斗地主了可是天算不如人算,撲克牌丟了幾張不全大熱天的,誰(shuí)愿意出去買(mǎi)牌啊。 原文:從零到一,擼一個(gè)在線(xiàn)斗地主(上篇) | AlloyTeam作者:TAT.vorshen 背景:朋友來(lái)深圳玩,若說(shuō)到在深圳有什么好玩的,那當(dāng)然是宅在家里斗地主了!可是天算不如人算,撲克牌丟了幾張不全……大熱天的,...

    raoyi 評(píng)論0 收藏0
  • 前端之從零開(kāi)始系列

    摘要:只有動(dòng)手,你才能真的理解作者的構(gòu)思的巧妙只有動(dòng)手,你才能真正掌握一門(mén)技術(shù)持續(xù)更新中項(xiàng)目地址求求求源碼系列跟一起學(xué)如何寫(xiě)函數(shù)庫(kù)中高級(jí)前端面試手寫(xiě)代碼無(wú)敵秘籍如何用不到行代碼寫(xiě)一款屬于自己的類(lèi)庫(kù)原理講解實(shí)現(xiàn)一個(gè)對(duì)象遵循規(guī)范實(shí)戰(zhàn)手摸手,帶你用擼 Do it yourself!!! 只有動(dòng)手,你才能真的理解作者的構(gòu)思的巧妙 只有動(dòng)手,你才能真正掌握一門(mén)技術(shù) 持續(xù)更新中…… 項(xiàng)目地址 https...

    Youngdze 評(píng)論0 收藏0
  • 小技巧 - 收藏集 - 掘金

    摘要:然而學(xué)習(xí)布局,你只要學(xué)習(xí)幾個(gè)手機(jī)端頁(yè)面自適應(yīng)解決方案布局進(jìn)階版附源碼示例前端掘金一年前筆者寫(xiě)了一篇手機(jī)端頁(yè)面自適應(yīng)解決方案布局,意外受到很多朋友的關(guān)注和喜歡。 十分鐘學(xué)會(huì) Fiddler - 后端 - 掘金一.Fiddler介紹 Fiddler是一個(gè)http抓包改包工具,fiddle英文中有欺騙、偽造之意,與wireshark相比它更輕量級(jí),上手簡(jiǎn)單,因?yàn)橹荒茏ttp和https數(shù)據(jù)...

    A Loity 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<