標準IO和系統IO的相關知識積累

小楠同志發表於2024-05-13

目錄
  • 檔案IO
    • 知識點補給
      • 1.FAT32與NTFS檔案系統的區別?
      • 2.MMU的概述和作用
      • 3.簡述Linux系統核心的作用
      • 4.瞭解Linux系統目錄和資料夾的區別
    • 標準IO介面
      • 一、開啟檔案
        • 函式1:fopen
      • 二、讀取資料
        • (1)字元讀取
        • 函式2:fgetc
        • 函式3:getc
        • 函式4:getchar
        • (2)按行讀取
        • 函式5:fgets
        • 函式6:gets
        • (3)按塊讀取
        • 函式7:fread
        • 函式8:feof
        • 函式9:ferror
      • 三、寫入檔案
        • (1)字元寫入
        • 函式10:fputc
        • 函式11:putc
        • 函式12:putchar
        • (2)按行寫入
        • 函式13:fputs
        • 函式14:puts
        • (3)按塊寫入
      • 四、關閉檔案
        • 函式15:fclose
      • 五、檔案位置
        • (1)設定位移
        • 函式:16fseek
        • (2)獲取位移
        • 函式17:ftell
      • 六、格式訪問
    • 系統IO介面
      • 一、開啟檔案
        • 函式18:open
      • 二、關閉檔案
        • 函式19:close
      • 三、檔案讀取
        • 函式20:read
      • 四、檔案寫入
        • 函式21:write
      • 四、位置位移
        • 函式22:lseek

檔案IO

知識點補給

1.FAT32與NTFS檔案系統的區別?

答:NTFS和FAT32是兩種不同的檔案系統格式,它們在功能、安全性和效能等方面存在一些區別。

1、功能和效能:NTFS是一種高度可恢復的檔案系統,具有許多高階功能,如資料恢復、加密、壓縮、磁碟配額等。相比之下,FAT32檔案系統在功能和效能方面較為有限。

2、磁碟分割槽大小:NTFS支援的磁碟分割槽大小最大可達2TB(2048GB),而FAT32支援的分割槽大小最大為32GB。因此,對於需要使用大容量磁碟的使用者來說,NTFS是更好的選擇。

3、單個檔案大小:NTFS突破了單個檔案4GB的容量限制,目前來說似乎沒容量限制,只要硬碟空間容量有多大,那麼就NTFS就可以分到多大。而FAT32在實際執行中不支援單個檔案大於4GB的檔案,一旦超過容量限制那麼系統就會提示磁碟空間不足。

4、安全性:NTFS提供了更高階的安全功能,可以對檔案和資料夾進行加密和許可權設定,而FAT32則不具備這樣的安全功能。在NTFS下,使用者可以對電腦使用者對該格式下所有的資料夾、檔案進行加密、修改、執行、讀取目錄及寫入許可權的設定。此外,在磁碟分割槽下任意資料夾或檔案上右鍵屬性,在高階屬性視窗中勾選中加密內容以便保護資料即可做到加密。

5、碎片和空間利用:隨著時間的推移和使用次數的增加,檔案可能會產生碎片。從FAT16的檔案系統格式,到之後的FAT32然後再到現在的NTFS檔案系統格式,從磁碟分割槽的格式不同,那麼所產品的磁碟碎片也是越來越小。

6、磁碟配額:NTFS支援磁碟配額,可以在一個NTFS分割槽上為不同使用者設定不同的磁碟空間配額,而FAT32不支援磁碟配額。

7、檔案恢復:NTFS具有更好的檔案恢復功能,可以恢復意外刪除或格式化的檔案,而FAT32的檔案恢復功能相對較弱。

8、壓縮和加密:NTFS支援檔案和資料夾的壓縮和加密,而FAT32不支援。

9、日誌記錄:NTFS支援事務日誌記錄,可以記錄對檔案系統的更改,而FAT32不支援。

10、檔案連結:NTFS支援硬連結和符號連結,而FAT32不支援。

11、檔案訪問控制:NTFS支援更復雜的檔案訪問控制,可以針對不同使用者或使用者組設定不同的訪問許可權,而FAT32不支援。

12、安全性:NTFS具有更高的安全性,可以防止惡意軟體或駭客對檔案進行修改或刪除,而FAT32的安全性相對較低。

綜上所述,NTFS和FAT32在功能、效能、磁碟分割槽大小、單個檔案大小、安全性和碎片和空間利用等方面存在顯著差異。因此,在選擇檔案系統格式時,需要根據實際需求和使用場景進行選擇。如果需要使用大容量磁碟並需要高階安全功能和資料恢復能力,則建議使用NTFS檔案系統。如果只需要一個簡單的檔案系統用於儲存少量資料,並且不需要高階功能,則FAT32檔案系統可能是一個更好的選擇。

2.MMU的概述和作用

MMU(Memory Manager Unit),中文名是記憶體管理單元,它是中央處理器(CPU)中用來管理虛擬儲存器、物理儲存器的控制線路,同時也負責虛擬地址對映為實體地址,以及提供硬體機制的記憶體訪問授權,多使用者多程序作業系統。

  • 1 虛擬地址到實體地址的對映。MMU負責將應用程式生成的邏輯地址(虛擬地址)轉換為實體地址,這使得程式可以使用比實際實體記憶體更大的地址空間。
  • 2 記憶體保護。透過設定訪問許可權位,MMU可以保護記憶體區域,防止程式訪問或修改關鍵資料。例如,它可以標記某些記憶體區域為只讀或禁止訪問。
  • 3虛擬記憶體管理。MMU實現了虛擬記憶體的概念,允許每個程序認為自己擁有整個實體記憶體,而實際上實體記憶體可能被多個程序共享。它負責將程序的虛擬地址對映到實體記憶體,以便多個程序能夠同時執行而不會相互干擾。
  • 4儲存器訪問許可權的控制。MMU可以控制對儲存器的訪問許可權,包括讀寫許可權。
  • 5設定虛擬儲存空間的Cache特性。MMU可以設定虛擬儲存空間的快取特性,以提高資料訪問的速度和效率。
  • 6處理頁面缺失和頁面替換演算法。MMU透過TLB(Translation Lookaside Buffer)來加速虛擬地址到實體地址的轉換,如果發生TLB缺失,MMU會使用頁面替換演算法來處理頁面替換,以保持實體記憶體的有效使用。
    總的來說,MMU是現代計算機系統中的重要組成部分,它透過虛擬記憶體管理、記憶體保護和地址對映等功能,極大地提高了計算機系統的記憶體管理效率和安全性。

3.簡述Linux系統核心的作用

Linux核心的功能主要是將應用層請求傳遞給硬體,並作為底層驅動程式,以間接控制定址系統中的各種裝置和元件。

  • 1.程序管理:Linux核心負責管理系統中執行的程序,包括程序的建立、排程、銷燬等操作,確保程序能夠正確地執行並共享系統資源。
  • 2.檔案系統管理:Linux核心提供檔案系統的支援,包括檔案的讀寫、許可權管理、檔案系統的掛載等操作,使得應用程式能夠方便地訪問和操作檔案。
  • 3.網路管理:Linux核心提供網路協議棧的支援,包括TCP/IP協議、網路裝置驅動等,使得計算機能夠進行網路通訊。
  • 4.記憶體管理:記憶體資源的使用策略對作業系統效能體現來說,尤為重要。記憶體在有限的記憶體資源上,為每一個程序建立了一個虛擬地址空間。核心的不同功能部分與記憶體管理子系統透過一套函式呼叫互動,使得通訊高效簡單。

4.瞭解Linux系統目錄和資料夾的區別

Linux中的目錄與Windows中的資料夾的含義是很容易混淆的,表面 上好像一致,實則不然。

  • Windows中的資料夾類似於一種容器,大檔案裡面存放了很多檔案以及子檔案,子檔案裡面又巢狀有別的資料夾,一層套一層,就好比俄羅斯套娃,不管怎麼套,裡面的總比外面的小,故在Windows中子檔案是不可能比外部檔案還大的。
  • Linux中的目錄並不是一種容器,而僅是一個檔案索引表,目錄下的檔案的真正的內容儲存在分割槽中的資料域區域。目錄中索引表的每一項稱為“目錄項”,裡面至少存放了一個檔案的名字(不含路徑部分)和索引號(分割槽唯一)。

標準IO介面

一、開啟檔案

函式1:fopen

  • 標頭檔案:
    #include<stdio.h>
  • fopen函式的功能:
    獲取指定檔案的檔案指標。
  • fopen函式作用的整體流程
    使用者可以在一個程式中利用fopen函式開啟多個檔案,每次開啟一個檔案,核心就會從堆記憶體中申請一塊FILE結構體大小的空間用來儲存檔案的所有資訊,然後按照檔案開啟的順序把每個開啟的檔案的結構體形成一條連結串列,然後使用連結串列頭進行管理。
  • 函式原型
    FILE*fopen(const char *pathname,const char *mode);
  • 函式引數:fopen有兩個引數
    引數一:const char *pathname:指的是開啟檔案的路徑,需要字串,例如 “demo.txt”,注意有具體檔名的話,即固定檔案,需要加“ ”。
    引數二:const char *mode:指的是訪問檔案的許可權。
    引數二選擇項如下:
    r:以只讀方式開啟檔案,要求檔案必須存在,游標在檔案開頭
    r+:以可讀可寫方式開啟檔案,要求檔案必須存在,游標在檔案開頭
    w:以只寫方式開啟檔案;如果檔案不存在則會建立新檔案,如果存在檔案則會將其內容清空;游標在檔案的開頭。
    w+:以可讀可寫方式開啟檔案;如果檔案不存在則會建立新檔案,如果存在檔案則會將其內容清空;游標在檔案的開頭。
    a:以只寫方式開啟檔案;如果檔案不存在則會建立新檔案;游標在檔案的末尾,意味著以追加的方式寫入內容。
    a+:以可讀可寫方式開啟檔案;如果檔案不存在則會建立新檔案;游標在檔案的末尾,意味著以追加的方式寫入內容。
  • 返回值
    成功:返回檔案指標(當前被開啟的檔案的檔案指標)
    失敗:返回NULL

思考fopen函式的返回值是一個指向被開啟檔案的FILE型別的指標,請問FILE型別是什麼?
回答:FILE型別其實是一個結構體資料型別,它包含了標準 I/O 庫函式為管理檔案所需要的所有資訊,比如包括用於實際I/O 的檔案描述符、指向檔案緩衝區的指標、緩衝區的長度、當前緩衝區中的位元組數以及出錯標誌等。
補充:kernel採用鏈式結構來管理被開啟的檔案,原因:FILE結構體型別中有一個成員是FILE型別的指標變數chain,該指標可以指向下一個被開啟檔案的檔案資訊區,也就是可以把FILE型別當做資料結構中的連結串列的結點,結點中除了可以儲存資料域之外,還可以利用指標域儲存下一個結點的地址。
注意:
開啟檔案的目的無非就是對檔案進行讀寫操作,所以每次當程式執行的時候已經有三個檔案流被開啟,分別是標準輸入stdin、標準輸出stdout、標準出錯stderr,這三者在stdio.h中也是FILE指標。
2.使用標準IO的時候,是不可以反覆關閉相同的檔案,因為釋放已經被釋放的堆記憶體,會導致段錯誤!!


二、讀取資料

標準C庫中提供了多個讀取函式,這些函式大體分為三類:字元讀取(fgetc)、按行讀取(fgets)、按塊讀取(fread)。

(1)字元讀取

函式2:fgetc

  • 標頭檔案:
    #include<stdio.h>
  • fgetc函式的功能
    獲取指定檔案的一個字元
  • fgetc函式作用流程
    從檔案指標stream指向的檔案中讀取一個字元,並在讀取一個位元組後把檔案的游標位置向後移一個位元組,然後讀取成功則把讀取到的字元所對應的ASCII碼透過返回值返回,讀取失敗則返回EOF。
  • 函式原型
    int fgetc(FILE *stream );
  • 函式引數:fgetc函式僅1個引數
    引數FILE *stream:指的是檔案指標
  • 結束條件
    檔案的游標已經到達檔案末尾或者遇到讀取錯誤時
  • 返回值
    成功:返回讀取字元的ASCII 碼
    失敗:返回EOF (EOF 是一個宏定義,宏定義的值為-1)
    另外,在標準庫中還提供了另一個函式getc(),這個函式的作用等效於fgetc()函式,只不過getc()函式的實現是利用宏定義而已。

函式3:getc

  • 標頭檔案:
    #include<stdio.h>
  • getc函式的功能
    獲取指定檔案的一個字元
  • getc函式的作用流程
    同fgetc函式作用流程一致
  • 函式原型
    int getc(FILE *stream );
  • 函式引數:getc函式僅1個引數
    引數FILE *stream:指的是檔案指標
  • 結束條件
    檔案的游標已經到達檔案末尾或者遇到讀取錯誤時
  • 返回值
    成功:返回讀取字元的ASCII 碼
    失敗:返回EOF (EOF 是一個宏定義,宏定義的值為-1)

函式4:getchar

  • 標頭檔案:
    #include<stdio.h>
  • getchar函式的作用流程及功能是
    getchar函式只能從標準輸入中獲取一個字元。
  • 函式原型
    int getchar(void );
  • 函式引數
    fgetc函式無引數
  • 結束條件
    檔案的游標已經到達檔案末尾或者遇到讀取錯誤時
  • 返回值
    成功:返回讀取字元的ASCII 碼
    失敗:返回EOF (EOF 是一個宏定義,宏定義的值為-1)

應用練習:在本地磁碟開啟一個儲存少量資料的文字demo.txt,利用fgetc函式把文字中的字元輸出到螢幕,當文字中所有字元都輸出完成後就結束程式。

(2)按行讀取

函式5:fgets

  • 標頭檔案:
    #include<sys/ioctl.h>;
  • fgets函式的功能:從指定檔案讀取最多一行資料
  • fgets函式的作用流程是
    從檔案指標stream指向的檔案中讀取一行字元,並把讀取的字元儲存在指標s所指向的字串內,當讀取到n-1個(n-1個指的是自定義緩衝區的最大容量為n-1)字元、或者已經讀取到檔案末尾(EOF)、或者讀取到換行符’\n’時,則函式呼叫停止。
  • 函式原型
    char *fgets(char *s,int n,FILE *stream );
  • 函式引數:fgets有三個引數
    引數一:char *s指的是自定義緩衝區指標
    引數二:int n指的是自定義緩衝區大小
    引數三:FILE *stream指的是即將被讀取資料的檔案指標。
  • 結束條件
    1.讀取到第n-1個字元
    2.讀取到檔案末尾
    3.讀取到換行符'\n'
  • 返回值
    成功:自定義緩衝區指標s
    失敗:NULL(檔案stream可能已經到達末尾或者遇到錯誤)

函式6:gets

  • 標頭檔案:
    #include<sys/ioctl.h>
  • gets函式的功能
    從指定檔案讀取最多一行資料
  • 函式作用流程是
    同fgets函式作用流程相同
  • 函式原型
    char *gets(char*s);
  • 函式引數:gets函式只有1個引數
    引數char*s指的是自定義緩衝區指標
  • 結束條件
    1.讀取到第n-1個字元
    2.讀取到檔案末尾
    3.讀取到換行符'\n'
  • 返回值
    成功:自定義緩衝區指標s
    失敗:NULL(檔案stream可能已經到達末尾或者遇到錯誤)
  • 備註:gets()缺失從檔案stdin讀入資料

思考為什麼fgets函式讀取到換行符\n時會結束?fgets函式中的引數n的意義是什麼??
回答:使用者呼叫fopen開啟檔案之後,可以把資料寫入到檔案中以及從檔案中讀取資料,但是實現讀取和寫入的過程中其實核心並沒有直接操作檔案,而是在操作指向檔案的結構體指標FILE,也就是使用者寫入的資料和讀取的資料會先儲存在FILE結構體的緩衝區中,當使用者呼叫重新整理緩衝區的函式或者其他讀寫函式時,FILE結構體的緩衝區會被重新整理,資料才會被系統寫入檔案。
根據IO裝置的不同,可以把緩衝區分為輸入緩衝區和輸出緩衝區,同樣,根據重新整理形式的不同,可以把緩衝區分為三種:全緩衝、行緩衝、無緩衝。
全緩衝:指的是當緩衝區被填滿就立即把資料沖刷到檔案、或者在關閉檔案、讀取檔案內容以及修改緩衝區型別時也會立即把資料沖刷到檔案,一般讀寫檔案的時候會採用
無緩衝:指的是沒有緩衝區,直接輸出,一般linux系統的標準出錯stderr就是採用無緩衝,這樣可以把錯誤資訊直接輸出。
行緩衝:指的是當緩衝區被填滿(一般緩衝區為4KB,就是4096位元組)或者緩衝區中遇到換行符’\n’時,或者在關閉檔案、讀取檔案內容以及修改緩衝區型別時也會立即把資料沖刷到檔案中,一般操作IO裝置時會採用,比如printf函式就是採用行緩衝。
注意:對於標準輸出stdout而言預設是採用行緩衝的,而對於標準出錯stderr而言預設是採用無緩衝的,對於普通檔案而言預設是採用全緩衝的。

image

(3)按塊讀取

函式7:fread

  • 標頭檔案:
    #include<sys/ioctl.h>
  • fread函式的功能
    從指定檔案讀取若干個資料塊
  • fread函式的作用流程
    從給定的檔案輸入流stream中讀取最多nmemb個塊到指標ptr指向的字串中,每個塊的大小為size位元組,函式返回成功讀取的塊的個數,若出現錯誤或到達檔案末尾,則可能小於nmemb。若size或nmemb為零,則fread函式返回0且不進行其他動作。
  • 函式fread的原型
    size_t fread (void *ptr,size_t size,size_t nmemb,FILE *stream);
  • 函式fread的引數: 函式fread有四個引數
    引數一:自定義緩衝區指標
    引數二:資料塊的大小
    引數三:資料塊的個數
    引數四:即將被讀取資料的檔案指標
  • 函式fread的返回值:
    成功:返回讀取的資料塊的個數,等於nmemb
    失敗:返回讀取的資料塊的個數,小於nmemb或等於0
  • 備註
    1.當返回小於nmemb時,檔案strem可能已經到達末尾,或者遇到錯誤
    2.當讀取資料發生錯誤時、讀取部分元素沒有讀全的情況下,檔案指示器的位置是不確定的。
    思考:可以知道函式的返回值如果小於nmemb則說明可能出現讀取錯誤或者到達檔案末尾,那應該如何區分這兩種情況?
    回答:可以透過標準庫中提供的兩個函式區分,一個函式是feof(),另一個則是ferror函式。

函式8:feof

  • feof函式的功能
    判斷fread函式返回值小於nmemb的原因是 到達檔案末尾
  • 標頭檔案:
    #include<stdio.h>
  • 函式feof的原型
    int feof(FILE *stream);
  • 函式fread的引數:函式feof有一個引數
    引數:指的是即將被讀取資料的檔案指標
  • 函式feof的返回值:
    返回0:檔案指示器的位置不在末尾
    返回非0:檔案指示器的位置位於末尾

函式9:ferror

  • ferror函式的功能
    判斷fread函式返回值小於nmemb的原因是 出現 讀取錯誤

  • 標頭檔案:
    #include<stdio.h>

  • 函式ferror的原型
    ferror(FILE *stream);

  • 函式ferror的引數:函式ferror有一個引數
    引數:指的是即將被讀取資料的檔案指標

  • 函式ferror的返回值:
    返回0:沒有出現讀取錯誤
    返回非0:出現了讀取錯誤


三、寫入檔案

(1)字元寫入

函式10:fputc

函式11:putc

函式12:putchar

  • fputc函式的功能
    將一個字元寫入一個指定的檔案,補充:如果檔案以追加的方式開啟,則字元會追加檔案的末尾
  • 標頭檔案:
    #include<stdio.h>
  • 函式fputc的原型
    int fputc(int c,FILE *stream);
    int putc(int c,FILE *stream);
    int putchar(int c);
  • 函式fputc的引數:函式fputc有兩個引數
    引數一int c:指的是待寫入的字元的ASCAII碼
    引數二FILE *stream:待寫入的檔案的指標
  • 函式fputc的返回值:
    成功:返回寫入的字元的ASCAII碼
    失敗:返回EOF

(2)按行寫入

函式13:fputs

函式14:puts

  • 函式fputs、puts的功能
    將資料寫入指定的檔案,補充:字串的結束符沒有被寫入到檔案中
  • 函式fputs、puts標頭檔案:
    #include<sys/ioctl.h>
  • 函式fputs、puts的原型
    int fputs(const char *s,FILE *stream);
    int puts(const char *s);
  • 函式fputs、puts的引數:函式fputs有兩個引數,函式puts有一個引數
    引數一const char *s:指的是自定義緩衝區指標
    引數二FILE *stream:指的是即將被寫入資料的檔案指標
  • 函式的返回值:
    成功:返回非負整數
    失敗:返回EOF
  • 備註:puts()缺失將資料寫入檔案stdout

(3)按塊寫入

  • fwrite函式的功能
    將若干塊資料寫入指定的檔案
  • fwrite標頭檔案:
    #include<sys/ioctl.h>
  • 函式fwrite的原型
    size_t fwrite(const void*ptr,size_t size,size_t nmemb,FILE *stream);
  • 函式fwrite的引數:函式rwrite有四個引數
    引數一:自定義緩衝區指標
    引數二:資料塊大小
    引數三:資料塊的個數
    引數四:即將被寫入資料的檔案指標
  • 函式fwirte的返回值:
    成功:返回寫入的資料塊個數,等於nmemb
    失敗:返回寫入的資料塊個數,小於nmemb或等於0

四、關閉檔案

函式15:fclose

  • 函式fclose的功能
    關閉指定的檔案並釋放其資源
  • fclose標頭檔案:
    #include<stdio.h>
  • 函式fclose的原型
    int fclose(FILE *stream);
  • 函式fclose的引數:函式fclose有一個引數
    引數:即將要關閉的檔案
  • 函式close的返回值:
    成功:返回0
    失敗:返回EOF

五、檔案位置

(1)設定位移

函式:16fseek

  • fseek函式的功能
    設定指定檔案的當前位置偏移量
  • 標頭檔案:
    #include<sys/ioctl.h>
  • 函式f的原seek型
    int fseek(FILE *stream,long int offset ,int whence);
  • 函式fseek的引數:函式fseek有三個引數
    引數一stream:需要設定位置偏移量的檔案指標
    引數二offset:新位置偏移量相對於基準點的偏移量(可正可負)
    引數三whence(基準點):
    ①:SEEK_SET:檔案開頭處
    ②:SEEK_CUR:當前位置
    ③:SEEK_END:檔案末尾處
  • 函式fseek的返回值:
    成功:返回0
    失敗:返回-1

(2)獲取位移

函式17:ftell

  • 函式ftell的功能
    獲取指定檔案的當前位置偏移量
  • 函式ftell標頭檔案:
    #include<sys/ioctl.h>
  • 函式ftell的原型
    long int ftell(FILE *stream);
  • 函式ftell的引數:函式有一個引數
    引數:需要返回當前檔案位置偏移量的檔案指標
  • 函式的返回值:
    成功:返回當前檔案位置偏移量
    失敗:返回-1
    fseek函式與ftell函式結合可用來求檔案大小

六、格式訪問

一般常用的關於檔案IO的格式化函式有printf、fprintf、scanf、fscanf、sprintf、snprintf


系統IO介面

System Calls:系統呼叫(Linux核心提供的API應用程式介面),SDK:軟體開發工具包,別人寫好的程式碼案例,SDK裡面有很多API

  • 基本概念
    Linux系統下“一切皆檔案”,即Linux系統下的資料和程式都是以檔案的形式儲存的,故Linux核心會提供一組操作檔案的函式介面,這組函式介面也被稱為系統IO;
    為了滿足使用者訪問檔案的需求以及提高使用者程式的可移植性,標準庫也提供了一組操作檔案的函式介面,這組函式介面也被稱為標準IO,是為了方便使用者在不同的作業系統下可以呼叫通用的函式來實現對檔案的讀寫訪問。
  • 標準IO與系統IO的區別標準I/O可以看成是在系統I/O的基礎上封裝了緩衝機制
    標準IO的優點是提供了緩衝區並且函式介面非常豐富,避免頻繁的系統呼叫,提高了I/O的效率;
    缺點是:沒有辦法針對某些型別的檔案(連結檔案、套接字檔案)進行訪問,所以一般適合訪問普通檔案。
    系統IO的優點是:可以針對特定型別檔案進行訪問,所以一般適合訪問資料需要實時重新整理的硬體裝置(LCD、觸控式螢幕......)。
    缺點是不具備輸入輸出緩衝區,沒辦法高效處理資料,原因是:因為系統呼叫的過程中核心要執行一系列的操作:首先核心需要捕獲呼叫,然後再檢查系統呼叫傳遞的引數的有效性,最後在使用者空間和核心空間之間傳輸資料。

一、開啟檔案

函式18:open

  • 函式open的功能
    一般可用於開啟驅動檔案,該函式在C99標準中是查不到的,可在man手冊的第二章查詢。
  • open標頭檔案:
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
  • 函式open的原型
    int open(const char *pathname,int flags);
    int open(const char *pathname,int flags,made_t mode);
  • 函式open的引數:函式open有兩個引數
    引數一:待開啟的檔案 路徑
    引數二:
    ① O_RDONLY , O_WRONLY , O_RDWR 必須三選一,或者用位運算子 | 來將標誌聯合使用
    引數三::
    O_CREAT(建立標誌,如果檔案不存在則建立),O_EXCL(如果呼叫了open函式時,使用了O_CREAT和O_EXCL,並且開啟的檔案是存在的,則open函式呼叫會失敗,如果檔案不存在,則會建立)
    注意:O_EXCL和O_CREAT一般是配套使用的,不能單獨使用
    補充:open函式的第三個引數mode只有在open函式的第二個引數flags使用O_CREAT或者O_TMPFILE才會使用,也就是說,開啟一個已經存在的檔案使用第一個版本的open函式即可,第二個版本的open函式的mode引數是指利用open函式建立新檔案時給新建立的檔案一個指定許可權,被建立的檔案的許可權其實就是Linux系統下檔案的許可權。
    image

注意:一般在Linux系統下可以直接使用shell命令來修改檔案的許可權,比如指令chmod 777 xxx.txt就是給該文件一個最高許可權。

  • 函式open的返回值:
    成功:檔案描述符:是一個小的非負整數,從一組數中選一個小的且未被使用的
    失敗:返回-1

二、關閉檔案

函式19:close

  • 函式close的功能
    關閉檔案(可理解為關閉1個檔案描述符)
  • 函式close標頭檔案:
    #include<unistd.h>
  • 函式open的原型
    int close(int fd);
  • 函式close的引數:函式close只有一個函式
    引數int fd:檔案描述符,是open的返回值。
  • 函式open的返回值:
    成功:返回0
    失敗:返回-1

三、檔案讀取

函式20:read

  • 函式read的功能
    read函式嘗試從fd對應的檔案中讀取最多count個位元組的資料並儲存到buf指向的緩衝區中
  • 函式read標頭檔案:
    #include<unistd.h>
  • 函式raed的原型
    ssize_t read(int fd,void *buf,size_tcount);
  • 函式read的引數:函式read有三個引數
    引數一int fd:檔案描述符,是open的返回值。
    引數二void *buf,讀到指定儲存空間的地址
    引數三size_tcount:讀取count個位元組
  • 函式read的返回值:返回讀取的位元組數量
    返回0: 讀取到檔案末尾
    返回-1:讀取出錯

四、檔案寫入

函式21:write

  • 函式write的功能
    函式write()函式會把引數buf所指的記憶體寫入count個位元組到引數fd所指的檔案內
  • 函式write標頭檔案:
    #include<unistd.h>
  • 函式write的原型
    ssize_t write(int fd,void *buf,size_tcount);
  • 函式write的引數:函式write有三個引數
    引數一int fd:輸入檔案描述符,是open的返回值。
    引數二void *buf,寫到指定儲存空間的地址
    引數三size_tcount:寫count個位元組
  • 函式write的返回值:成功寫入檔案的位元組數
    返回0:寫入文件的位元組數
    返回-1:寫入出錯

四、位置位移

函式22:lseek

  • 函式lseek的功能
    設定檔案的位置指示器的位移
  • 函式lseek標頭檔案:
    #include<unistd.h>
    #include<sys/types.h>
  • 函式lseek的原型
    off_t lseek(int fd,off_t offset,int whence);
  • 函式lseek的引數:函式write有三個引數
    引數一int fd:輸入檔案描述符,是open的返回值。
    引數二off_t offset:偏移量
    引數三int whence:
    檔案開頭:SEEK_SET
    當前位置:SEEK_CUR
    檔案末尾:SEEK_END
  • 函式lseek的返回值:
    成功:返回檔案位置指示器相較於開頭的偏移量,以位元組為單位
    失敗:返回-1

相關文章