[搬家帖]Linux檔案操作

來源:互聯網
上載者:User

一、檔案系統

    檔案系統的作用就是將檔案組織成包含目錄、串連等存在於物理塊裝置中的邏輯階層。它不關心底層的物理塊裝置的結構,當對檔案進行操作時,由塊裝置驅動程式將對某個特定塊的請求映射到正確的裝置上去。
    Ext3檔案系統將整個檔案系統表示成一個單一的層次樹,將檔案儲存在大小相同的資料區塊中。資料區塊越小,磁碟空間利用率越高,但由於核心需要進行的I/O操作次數增多,運行速度有所降低;資料區塊越大,速度有所提高,但磁碟利用率又降低了。
    Ext3通過一個inode結構來描述檔案,inode結構中包含檔案的存取許可權、修改時間、檔案類型等資訊。所有inode都儲存在inode表中,目錄檔案僅僅是儲存指向inode表項索引號的一個鏈表,前兩個入口總是.和..,表示目前的目錄和父目錄。

二、檔案描述符和流

    檔案描述符是開啟或建立檔案時Linux核心分配的一個非負整數,用來跟蹤開啟的檔案。有3個檔案描述符有特定意義:0-標準輸入,1-標準輸出,2-標準錯誤,在POSIX標準中定義了3個常量來表示這3個檔案描述符:STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO。要使用這些常量,必須包含標頭檔<unistd.h>
    流是標準C語言I/O庫提出來的概念,隱藏了檔案描述符,以更抽象的概念代替。用標準I/O庫函數開啟或建立檔案時,返回一個FILE結構的指標,該結構包含了檔案描述符、緩衝區地址、緩衝區大小等資訊。有3個預定義的流於3個預定義的檔案描述符對應:stdin,stdout,stderr,要使用這3個流必須包含標頭檔<stdio.h>

三、檔案操作

    檔案操作分為系統調用和標準C庫函數兩種。系統調用就是作業系統提供的一些調用介面,因此與作業系統相關,而標準C庫是與作業系統無關的。這裡主要介紹系統調用。

    1.開啟/關閉檔案
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <fcntl.h>
        int open(const char *pathname, int flag);
        int open(const char *pathname, int flag, mode_t mode);
        int creat(const char *pathname, mode_t mode);
        int close(int fd);
    其中flag參數為以下值:
        O_RDONLY:唯讀
        O_WRONLY:唯寫
        O_RDWR:讀寫
        O_APPEND:追加
        O_CREAT:檔案不存在則建立,需要制定mode參數
        O_EXCL:如果指定了O_CREAT並且檔案已存在則返回錯誤
        O_TRUNC:如果檔案存在並且以唯寫方式開啟,則把檔案內容清空
        O_NDELAY:以非阻塞方式開啟。正常檔案位於本地磁碟,完成讀寫操作的時間是確定的,因此總是阻塞的。但是當進程對某些特殊檔案如FIFO進行操作時,資料到達的時間是不確定的,因此讀操作需要立即返回而不是阻塞。
        O_SYNC:將緩衝區的資料同步到磁碟上
        O_NOFOLLOW:如果pathname是一個符號串連檔案,open()函數返回一個錯誤
        O_DIRECTORY:如果pathname不是一個目錄,open()函數返回一個錯誤
    其中mode只有在指定了O_CREAT標誌時才需要,指定新建立的檔案的存取許可權(mode & ~umask)
        S_IRUSR:擁有者讀許可權
        S_IWUSR:擁有者寫入權限
        S_IXUSR:擁有者執行許可權
        S_IRWXU:擁有者讀、寫、執行許可權
        S_IRGRP:組讀許可權
        S_IWGRP:組寫入權限
        S_IXGRP:組執行許可權
        S_IRWXG:組讀、寫、執行許可權
        S_IROTH:其他使用者讀許可權
        S_IWOTH:其他使用者寫入權限
        S_IXOTH:其他使用者執行許可權
        S_IRWXO:其他使用者讀、寫、執行許可權

    2.讀/寫檔案
        #include <unistd.h>
        size_t write(int fildes, const void *buf, size_t nbytes);
        size_t read(int fildes, void *buf, size_t nbytes);

    3.檔案定位
        #include <unistd.h>
        #include <sys/types.h>
        off_t lseek(int fildes, off_t offset, int whence);
    其中whence可以有以下3個值,與標準C庫是一致的:
        SEEK_SET:相對於檔案開頭
        SEEK_CUR:相對於當前位置
        SEEK_END:相對於檔案結尾

    4.查詢檔案狀態資訊
        #include <unistd.h>
        #include <sys/stat.h>
        #include <sys/types.h>
        int fstat(int fildes, struct stat *buf);
        int stat(const char *path, struct stat *buf);
        int lstat(const char *path, struct stat *buf);
    其中fstat()與stat()功能是相同的,只是參數不同。當檔案是一個符號連結時,lstat()將返回這個連結的資訊,而stat()將返回這個連結指向的檔案的資訊。
    stat是一個結構體,作為參數傳遞,包含以下成員:
        st_mode        檔案許可權以及檔案類型資訊
        st_ino        檔案I節點資訊
        st_dev        檔案所在的裝置資訊
        st_uid        檔案所有者的使用者標識
        st_gid        檔案所有者的組標識
        st_atime    上一次訪問的時間
        st_ctime    上一次對許可權,所有者,組,或是內容的修改時間
        st_mtime    上一次對內容的修改時間
        st_nlink    到這個檔案的永久連結數目
    其中st_mode成員包含了檔案許可權和檔案類型資訊。
    檔案許可權和open()函數中的mode參數的取值相同
    檔案類型可以取以下值:
        S_IFBLK:實體是一個特殊的塊裝置
        S_IFDIR:實體是一個目錄
        S_IFCHR:實體是一個特殊的字元裝置
        S_IFIFO:實體是一個IFIFO(命令管道)
        S_IFREG:實體是一個常規檔案
        S_IFLNK:實體是一個符號連結
    要測試這些標誌,首先要將它們取出來,就需要用到掩碼(mask):
        S_IFMT:檔案類型
        S_IRWXU:使用者讀/寫/執行許可權
        S_IRWXG:組讀/寫/執行許可權
        S_IRWXO:其他使用者讀/寫/執行許可權
    這些掩碼的作用就是把其他位都屏蔽掉,只留下要測試的標誌位。
    除了通過測試檔案類型標誌來獲得檔案類型,還有一些宏可以協助我們來進行判斷,使用也非常方便,把st_mode作為參數傳進去就可以了:
        S_ISBLK():為特殊的塊檔案測試
        S_ISCHR():為特殊的字元檔案測試
        S_ISDIR():為目錄測試
        S_ISFIFO():為FIFO測試
        S_ISREG():為常規檔案測試
        S_ISLNK():為符號連結測試
    舉例:
        struct stat statbuf;
        mode_t modes;
        stat("filename", &statbuf);
        modes = statbuf.st_mode;
    用宏來測試:
        if(!S_ISDIR(modes))//判斷是否不是目錄
    用標誌位來測試:
        if((modes & S_IRWXU) & S_IXUSR)//判斷是否有使用者執行許可權

    5.檔案描述符與流之間的轉換
        #include <stdio.h>
        FILE *fdopen(int filedes, const char *mode);
        mode參數與fopen()函數相同

    6.進階主題
        #include <fcntl.h>
        int fcntl(int fildes, int cmd);
        int fcntl(int fildes, int cmd, long arg);
    fcntl()函數可以用來查詢和改變一個已被開啟的檔案的屬性。
    cmd參數可以取以下值:
        F_DUPFD:複製檔案描述符,與dup()/dup2()函數功能相同
        F_GETFD/F_SETFD:查詢/設定檔案描述符標誌,通常只是FD_CLOEXEC標誌
        F_GETFL/F_SETFL:查詢/設定檔案狀態標誌,與open()函數的第二個參數取值相同
    注意:由於O_RDONLY、O_WRONLY、O_RDWR標誌並不是各佔一位(O_RDWR=O_RDONLY|O_WRONLY),如果要測試檔案的讀寫權限,需要先用O_ACCMODE與傳回值相與,然後再與這3個標誌進行比較
    另外,檔案的讀寫權限是不能被改變的,只能改變O_APPEND、O_NONBLOCK、O_SYNC、O_ASYNC這4個標誌

        #include <unistd.h>
        #include <sys/ioctl.h>
        int ioctl(int filedes, int request, ...);
    凡是其他函數不能完成的I/O操作一般都由它來完成,request參數指定要對檔案進行何種操作,操作不同,第三個參數也不同:
        DIOxxx:磁碟I/O
        FIOxxx:檔案I/O
        MTIOxxx:磁帶I/O
        SIOxxx:通訊端I/O
        TIOxxx:終端I/O

    7.緩衝與無緩衝
    (1)完全緩衝。標準C庫函數對檔案的操作一般是完全緩衝。只有當I/O緩衝區被填滿(寫操作)或者為空白(讀操作)時,核心才會進行真正的I/O操作。核心一般在對第一個流進行第一次I/O操作時調用malloc()一類的函數分配緩衝區。
    (2)行緩衝。當檔案實際是一個終端時,一般使用行緩衝。採用行緩衝後,只有遇到分行符號時才進行真正的I/O操作。注意的是,由於I/O庫中的緩衝區大小有限,因此當一行很長時有可能在沒有遇到分行符號時就已經進行I/O操作了。
    (3)無緩衝。一般標準錯誤都是無緩衝的,輸出的任何資訊都會立即反應到檔案中。
    設定流的緩衝類型:
        #include <stdio.h>
        void setbuf(FILE *fp, char *buf);
        void setvbuf(FILE *fp, char *buf, int mode, size_t size);
    把setbuf()函數中的buf參數設定為NULL,就是無緩衝類型。要允許緩衝,則buf必須指向一個長度至少為BUFSIZE(定義在<stdio.h>中)的緩衝區。如果該流是一個終端,則被設定為行緩衝,否則為完全緩衝。
    把setvbuf()中的mode參數設定為_IONBF,則為無緩衝類型,buf和size參數被忽略。把mode參數設定為_IOFBF(完全緩衝)或_IOLBF(行緩衝)時,size指定buf所指向的緩衝區的大小。如果buf是NULL則I/O庫函數會根據stat結構中的st_blksize成員自動分配一個緩衝區。如果系統無法決定該值,如該檔案是一個裝置或管道時,緩衝區大小就是BUFSIZE。
強制輸出緩衝區內容:int fflush(FILE *fp); 如果fp為NULL,則flush所有被開啟的流。

    8.錯誤處理
    出錯時通過設定全域變數errno的值來指示錯誤原因
    將錯誤號碼映射為一個字串
        #include <string.h>
        char *strerror(int errnum);   

    將錯誤資訊輸出到標準錯誤流,以“s: ”為首碼
        #include <stdio.h>
        void perror(const char *s);

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.