博客專欄

EEPW首頁 > 博客 > 嵌入式Linux:文件I/O和標(biāo)準(zhǔn)I/O庫

嵌入式Linux:文件I/O和標(biāo)準(zhǔn)I/O庫

發(fā)布人:美男子玩編程 時間:2024-05-30 來源:工程師 發(fā)布文章

文件 I/O (Input/Output)和標(biāo)準(zhǔn) I/O 庫是用于在 C 語言中進(jìn)行文件操作的兩種不同的方法。

1文件I/O

文 I/O(Input/Output)是指程序與文件之間進(jìn)行數(shù)據(jù)交換的過程。在計算機(jī)編程中,文件 I/O 是通過讀取和寫入文件來實現(xiàn)數(shù)據(jù)的輸入和輸出操作。文件 I/O 主要涉及打開文件、讀取文件內(nèi)容、寫入文件內(nèi)容和關(guān)閉文件等操作。


常見文件 I/O 操作包括使用系統(tǒng)調(diào)用(如 open()、read()、write()、close())來進(jìn)行文件操作。通過文件 I/O,程序可以從文件中讀取數(shù)據(jù),對數(shù)據(jù)進(jìn)行處理,然后將結(jié)果寫入文件中,實現(xiàn)數(shù)據(jù)的持久化存儲和處理。


在Linux系統(tǒng)中,一切皆文件是其核心設(shè)計理念之一,因此文件I/O操作在Linux系統(tǒng)中顯得尤為重要。


1.1、文件描述符


文件描述符是操作系統(tǒng)中用于標(biāo)識打開文件的整數(shù)值。它是進(jìn)程與文件之間的橋梁,允許進(jìn)程對文件進(jìn)行讀取、寫入和其他操作。在Linux系統(tǒng)中,每個打開的文件都與一個文件描述符相關(guān)聯(lián),這個文件描述符是一個非負(fù)整數(shù),通常是從0開始遞增的。


文件描述符直接與操作系統(tǒng)的文件表項相關(guān)聯(lián),是操作系統(tǒng)提供的抽象。


舉例來說,假設(shè)我們有一個C語言程序,打開了一個名為“example.txt”的文本文件進(jìn)行讀取。在這個程序中,文件描述符是用于表示這個打開的文件的整數(shù)值。當(dāng)程序調(diào)用open函數(shù)打開文件時,操作系統(tǒng)會分配一個文件描述符,并將其返回給程序。程序可以使用這個文件描述符執(zhí)行讀取操作,如讀取文件內(nèi)容并將其輸出到終端上。


#include#include#include

int main() {    int fd; // 文件描述符    char buf[1024]; // 用于存儲讀取的數(shù)據(jù)
   // 打開文件 example.txt    fd = open("example.txt", O_RDONLY);    if (fd == -1) {        perror("open");        return 1;    }
   // 讀取文件內(nèi)容并輸出到終端上    ssize_t bytes_read;    while ((bytes_read = read(fd, buf, sizeof(buf))) > 0) {        write(STDOUT_FILENO, buf, bytes_read);    }
   // 關(guān)閉文件    close(fd);
   return 0;}


在這個示例中,open函數(shù)打開文件example.txt并返回一個文件描述符,然后read函數(shù)使用這個文件描述符來從文件中讀取數(shù)據(jù)。最后,close函數(shù)關(guān)閉文件,并釋放對應(yīng)的文件描述符。


1.2、open打開文件

在Linux系統(tǒng)中,操作文件需要先打開它以獲取文件描述符,然后進(jìn)行讀寫或其他操作,最后關(guān)閉文件。open函數(shù)可用于打開現(xiàn)有文件或創(chuàng)建新文件。函數(shù)原型如下所示:


#include#include#include
int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);


函數(shù)的參數(shù)和返回值含義如下:


  • pathname:字符串類型,用于標(biāo)識需要打開或創(chuàng)建的文件。它可以包含路徑信息,可以是絕對路徑或相對路徑,例如:"./src_file"(當(dāng)前目錄下的 src_file 文件)或 "/home/dengtao/hello.c"。如果 pathname 是一個符號鏈接,open 函數(shù)會對其進(jìn)行解引用。

  • flags:調(diào)用 open 函數(shù)時需要提供的標(biāo)志,包括文件訪問模式標(biāo)志以及其他文件相關(guān)標(biāo)志。這些標(biāo)志使用宏定義進(jìn)行描述,并都是常量。open 函數(shù)提供了豐富的標(biāo)志選項,我們可以單獨(dú)使用某一個標(biāo)志,也可以通過位或運(yùn)算(|)將多個標(biāo)志進(jìn)行組合。

  • mode:用于指定新建文件的訪問權(quán)限,僅在flags參數(shù)中包含O_CREAT或O_TMPFILE標(biāo)志時有效。在Linux系統(tǒng)中,權(quán)限對于文件是一個重要的屬性。我們可以使用touch命令在Linux系統(tǒng)中創(chuàng)建一個文件,此時文件會有默認(rèn)的權(quán)限。如果需要修改文件權(quán)限,可以使用chmod命令進(jìn)行修改。例如,在Linux系統(tǒng)下,我們可以使用ls -l命令查看文件對應(yīng)的權(quán)限。

  • 返回值:成功將返回文件描述符,文件描述符是一個非負(fù)整數(shù);失敗將返回-1。


open函數(shù)的flags參數(shù)用于指定打開文件時的行為和權(quán)限。下面是一些常用的flags參數(shù)值:


  • O_RDONLY:只讀方式打開文件。

  • O_WRONLY:只寫方式打開文件。

  • O_RDWR:讀寫方式打開文件。

  • O_CREAT:如果文件不存在,則創(chuàng)建文件。

  • O_EXCL:與O_CREAT一同使用,如果文件已經(jīng)存在,則返回錯誤。

  • O_TRUNC:如果文件存在且為只寫或讀寫打開,則將其長度截斷為0。

  • O_APPEND:追加方式打開文件,在寫入數(shù)據(jù)時追加到文件末尾。

  • O_NONBLOCK:非阻塞方式打開文件,在沒有數(shù)據(jù)可讀取時不阻塞。

  • O_SYNC:同步寫入方式打開文件,對寫入文件的每個操作進(jìn)行同步。

  • O_DIRECT:直接IO方式打開文件,繞過系統(tǒng)緩存,數(shù)據(jù)直接讀寫到磁盤。

  • O_TMPFILE:創(chuàng)建一個臨時文件,文件在關(guān)閉時自動刪除。


open函數(shù)的常用的mode參數(shù):


  • S_IRUSR:文件所有者讀權(quán)限。

  • S_IWUSR:文件所有者寫權(quán)限。

  • S_IXUSR:文件所有者執(zhí)行權(quán)限。

  • S_IRGRP:文件組用戶讀權(quán)限。

  • S_IWGRP:文件組用戶寫權(quán)限。

  • S_IXGRP:文件組用戶執(zhí)行權(quán)限。

  • S_IROTH:其他用戶讀權(quán)限。

  • S_IWOTH:其他用戶寫權(quán)限。

  • S_IXOTH:其他用戶執(zhí)行權(quán)限。


在應(yīng)用程序中使用 open 函數(shù)時,需要包含 3 個頭文件“#include”、“#include”、“#include”。


下面是一個使用 open 函數(shù)的簡單示例:


#include#include#include#include
int main() {    const char *filename = "example.txt";    int fd;
   // 使用 open 函數(shù)打開文件,如果文件不存在,則創(chuàng)建    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);    if (fd == -1) {        perror("open");        exit(EXIT_FAILURE);    }
   // 向文件寫入內(nèi)容    if (write(fd, "Hello, World!", 13) == -1) {        perror("write");        close(fd);        exit(EXIT_FAILURE);    }
   // 關(guān)閉文件    if (close(fd) == -1) {        perror("close");        exit(EXIT_FAILURE);    }
   printf("File created and written successfully.n");
   return 0;}


在這個示例中:


  • 我們首先定義了一個文件名 example.txt。

  • 使用 open 函數(shù)打開文件,使用 O_WRONLY 標(biāo)志表示以只寫方式打開文件,O_CREAT 標(biāo)志表示如果文件不存在則創(chuàng)建,O_TRUNC 標(biāo)志表示如果文件存在則將其截斷為空文件,最后一個參數(shù) S_IRUSR | S_IWUSR 指定了新創(chuàng)建文件的權(quán)限為用戶可讀可寫。

  • 如果 open 函數(shù)調(diào)用失敗,會打印錯誤消息并退出程序。

  • 使用 write 函數(shù)向文件中寫入內(nèi)容。

  • 最后使用 close 函數(shù)關(guān)閉文件。


1.3、write寫文件


write 函數(shù)用于將數(shù)據(jù)寫入文件。其函數(shù)原型如下:


#include
ssize_t write(int fd, const void *buf, size_t count);


函數(shù)的參數(shù)和返回值含義如下:


  • fd:文件描述符,代表要寫入數(shù)據(jù)的文件。需要將要寫入數(shù)據(jù)的文件對應(yīng)的文件描述符傳遞給 write 函數(shù)。

  • buf:指定要寫入數(shù)據(jù)的緩沖區(qū)。

  • count:指定要寫入的字節(jié)數(shù)。

  • 返回值:成功時返回寫入的字節(jié)數(shù)(0 表示未寫入任何字節(jié))。如果返回值小于 count 參數(shù),這不一定是錯誤,例如磁盤空間已滿可能導(dǎo)致未寫入所有字節(jié)。如果寫入出錯,則返回 -1。



對于普通文件,無論是讀取還是寫入,一個關(guān)鍵問題是確定從文件的哪個位置開始進(jìn)行操作。即所謂的I/O操作位置偏移量。讀寫操作都從文件的當(dāng)前位置偏移量開始。默認(rèn)情況下,當(dāng)前位置偏移量通常是0,即指向文件的起始位置。隨著read、write函數(shù)的調(diào)用,當(dāng)前位置偏移量也會相應(yīng)移動。例如,如果當(dāng)前位置偏移量為1000字節(jié),調(diào)用write()寫入或read()讀取500字節(jié)后,當(dāng)前位置偏移量將移動到1500字節(jié)處。


使用 write 函數(shù)需要先包含 unistd.h 頭文件。


下面是一個示例代碼,將字符串寫入文件:


#include#include#include
int main() {    int fd = open("example.txt", O_WRONLY | O_CREAT, 0644);    if (fd == -1) {        perror("open");        return 1;    }
   const char *message = "Hello, world!";    ssize_t bytes_written = write(fd, message, strlen(message));    if (bytes_written == -1) {        perror("write");        close(fd);        return 1;    }
   close(fd);    printf("Data written successfully.n");    return 0;}


在此示例中,我們首先打開了一個文件 example.txt 以供寫入,然后使用 write 函數(shù)將字符串 "Hello, world!" 寫入文件中。 


1.4、read讀文件

調(diào)用 read 函數(shù)可從打開的文件中讀取數(shù)據(jù),其函數(shù)原型如下所示:

#include
ssize_t read(int fd, void *buf, size_t count);


函數(shù)參數(shù)和返回值含義如下:

  • fd:文件描述符,用于標(biāo)識要讀取的文件。

  • buf:用于存儲讀取數(shù)據(jù)的緩沖區(qū)。

  • count:需要讀取的字節(jié)數(shù)。

  • 返回值:如果讀取成功,返回讀取到的字節(jié)數(shù)。實際讀取到的字節(jié)數(shù)可能小于請求的字節(jié)數(shù),也可能為0,例如當(dāng)文件已到達(dá)末尾時。



使用 read 函數(shù)需要先包含 unistd.h 頭文件。


例如,下面是一個簡單的示例,從文件中讀取數(shù)據(jù):


#include#include#include#include
#define BUF_SIZE 1024
int main() {    int fd;    ssize_t bytes_read;    char buffer[BUF_SIZE];
   // 打開文件    fd = open("example.txt", O_RDONLY);    if (fd == -1) {        perror("open");        exit(EXIT_FAILURE);    }
   // 讀取文件內(nèi)容    bytes_read = read(fd, buffer, BUF_SIZE);    if (bytes_read == -1) {        perror("read");        exit(EXIT_FAILURE);    }
   // 輸出讀取的內(nèi)容    write(STDOUT_FILENO, buffer, bytes_read);
   // 關(guān)閉文件    close(fd);
   return 0;}



這個示例打開一個名為example.txt的文件,從中讀取數(shù)據(jù)并將其寫入標(biāo)準(zhǔn)輸出。



1.5、close關(guān)閉文件


close 函數(shù)用于關(guān)閉一個已經(jīng)打開的文件描述符,釋放對應(yīng)的資源。在Linux系統(tǒng)中,文件描述符是有限資源,因此在不再需要使用文件時,應(yīng)該及時關(guān)閉,以釋放資源并避免資源泄漏。


函數(shù)原型如下所示:


#include
int close(int fd);


函數(shù)參數(shù)和返回值含義如下:


  • fd:文件描述符,需要關(guān)閉的文件所對應(yīng)的文件描述符。

  • 返回值:如果成功返回 0,如果失敗則返回-1。

使用 close 函數(shù)需要先包含頭文件。


以下是一個簡單的示例,演示如何使用 close 函數(shù)關(guān)閉文件:


#include#include#include#include
int main() {    // 打開一個文件,獲取文件描述符    int fd = open("example.txt", O_RDONLY);    if (fd == -1) {        perror("open");        exit(EXIT_FAILURE);    }
   // 關(guān)閉文件    if (close(fd) == -1) {        perror("close");        exit(EXIT_FAILURE);    }
   printf("File closed successfully.n");
   return 0;}



在這個例子中,首先通過 open 函數(shù)打開了一個文件,然后使用 close 函數(shù)關(guān)閉了文件描述符。perror 函數(shù)用于打印出發(fā)生錯誤的詳細(xì)信息。


除了使用 close 函數(shù)顯式關(guān)閉文件之外,在 Linux 系統(tǒng)中,當(dāng)一個進(jìn)程終止時,內(nèi)核會自動關(guān)閉它打開的所有文件。這意味著如果一個程序在退出時沒有關(guān)閉已打開的文件,內(nèi)核會代為關(guān)閉這些文件。許多程序都依賴于這一特性,因此沒有顯式地使用 close 函數(shù)來關(guān)閉文件。


然而,顯式關(guān)閉不再需要的文件描述符通常是良好的編程習(xí)慣。這樣做可以提高代碼的可讀性和可靠性,并確保在后續(xù)修改時代碼的行為符合預(yù)期。此外,釋放不再需要的文件描述符可以有效地管理有限的系統(tǒng)資源。


2


標(biāo)準(zhǔn)I/O庫


標(biāo)準(zhǔn)I/O庫是C語言中用于進(jìn)行輸入和輸出操作的標(biāo)準(zhǔn)庫之一。它提供了一組函數(shù)和數(shù)據(jù)結(jié)構(gòu),用于與文件、終端設(shè)備、管道等進(jìn)行交互,使得程序可以方便地進(jìn)行輸入和輸出操作,而無需直接操作文件描述符。


標(biāo)準(zhǔn)I/O庫函數(shù)構(gòu)建在文件I/O系統(tǒng)調(diào)用(如 open()、read()、write()、lseek()、close() 等)之上。例如,fopen() 利用 open() 系統(tǒng)調(diào)用打開文件,fread() 利用 read() 系統(tǒng)調(diào)用讀取文件,fwrite() 利用 write() 系統(tǒng)調(diào)用寫入文件等。


盡管標(biāo)準(zhǔn)I/O和文件I/O都是C語言函數(shù),但它們有明顯區(qū)別:


  • 標(biāo)準(zhǔn) I/O 是標(biāo)準(zhǔn) C 庫函數(shù),而文件 I/O 是 Linux 系統(tǒng)調(diào)用;

  • 標(biāo)準(zhǔn) I/O 是文件 I/O 的封裝,實際上調(diào)用文件 I/O 完成操作;

  • 可移植性方面,標(biāo)準(zhǔn) I/O 更優(yōu),因為不同操作系統(tǒng)的系統(tǒng)調(diào)用接口不同,而標(biāo)準(zhǔn) I/O 接口幾乎相同;

  • 在性能和效率方面,標(biāo)準(zhǔn) I/O 由于維護(hù)自己的緩沖區(qū),性能更高,而文件 I/O 在用戶空間無緩存。


標(biāo)準(zhǔn)I/O庫通常包含在C標(biāo)準(zhǔn)庫中,其函數(shù)和數(shù)據(jù)結(jié)構(gòu)被定義在頭文件中。一些常用的標(biāo)準(zhǔn)I/O函數(shù)包括fopen、fclose、fread、fwrite、fprintf、fscanf等。所以使用時候需要在程序源碼中包含頭文件。


標(biāo)準(zhǔn)I/O庫的主要特點包括:


  • 緩沖機(jī)制:標(biāo)準(zhǔn)I/O庫通常使用緩沖區(qū)來提高性能。例如,在輸出時,數(shù)據(jù)首先寫入到緩沖區(qū),然后在適當(dāng)?shù)臅r機(jī)才會被刷新到實際的輸出設(shè)備上,從而減少了系統(tǒng)調(diào)用的次數(shù),提高了效率。

  • 格式化輸入輸出:標(biāo)準(zhǔn)I/O庫提供了格式化輸入輸出的功能,例如printf和scanf函數(shù)允許以特定格式輸出和輸入數(shù)據(jù),使得數(shù)據(jù)的處理更加方便。

  • 文件操作:標(biāo)準(zhǔn)I/O庫提供了一系列函數(shù)用于文件的打開、關(guān)閉、讀取、寫入等操作,例如fopen、fclose、fread、fwrite等。

  • 錯誤處理:標(biāo)準(zhǔn)I/O庫提供了一套錯誤處理機(jī)制,允許程序員檢測和處理輸入輸出操作中可能出現(xiàn)的錯誤情況。

使用標(biāo)準(zhǔn)I/O庫可以使得程序更加可移植,因為它們提供了對底層系統(tǒng)調(diào)用的封裝,使得程序不依賴于特定的操作系統(tǒng)或文件系統(tǒng)。因此,標(biāo)準(zhǔn)I/O庫是C語言中進(jìn)行文件操作和輸入輸出的主要方式之一。


2.1、FILE指針

標(biāo)準(zhǔn)I/O庫函數(shù)操作圍繞FILE指針展開。調(diào)用標(biāo)準(zhǔn)I/O庫函數(shù)打開或創(chuàng)建文件時,返回一個指向FILE類型對象的指針(FILE *),該指針與被打開或創(chuàng)建的文件相關(guān)聯(lián),用于后續(xù)的標(biāo)準(zhǔn)I/O操作。因此,F(xiàn)ILE指針在標(biāo)準(zhǔn)I/O庫中扮演了與文件描述符類似的角色,但用于更高級別的操作。


FILE結(jié)構(gòu)體包含了標(biāo)準(zhǔn)I/O庫函數(shù)所需的所有文件管理信息,如文件描述符、文件緩沖區(qū)指針、緩沖區(qū)長度、當(dāng)前緩沖區(qū)字節(jié)數(shù)以及出錯標(biāo)志等。


當(dāng)使用標(biāo)準(zhǔn)I/O庫函數(shù)打開或創(chuàng)建文件時,會返回一個指向FILE類型對象的指針,該指針與被打開或創(chuàng)建的文件相關(guān)聯(lián)。下面是一個簡單的示例:


#include
int main() {    FILE *file_ptr;
   // 使用標(biāo)準(zhǔn)I/O庫函數(shù)打開文件    file_ptr = fopen("example.txt", "w");    if (file_ptr == NULL) {        printf("Failed to open file.n");        return 1;    }
   // 使用 FILE 指針進(jìn)行寫入操作    fprintf(file_ptr, "Hello, world!n");
   // 關(guān)閉文件    fclose(file_ptr);
   return 0;}

在這個示例中,file_ptr指針與文件相關(guān)聯(lián),用于后續(xù)的標(biāo)準(zhǔn)I/O操作(寫入操作)。通過FILE指針,我們可以方便地進(jìn)行文件的讀寫操作,而不必直接操作文件描述符和底層的文件系統(tǒng)。


2.2、fopen打開文件

fopen() 是C語言標(biāo)準(zhǔn)庫中用于打開文件的函數(shù)之一。它的原型如下:




FILE *fopen(const char *filename, const char *mode);



函數(shù)參數(shù)和返回值含義如下:


  • path:參數(shù) path 是一個指向文件路徑的指針,可以是文件的絕對路徑或相對路徑。這個路徑指定了要打開或創(chuàng)建的文件的位置和名稱。

  • mode:參數(shù) mode 是一個字符串,指定了對文件的讀寫權(quán)限。它描述了打開或創(chuàng)建文件時所需的操作類型。常見的模式包括:

    • "r":只讀模式,用于打開一個已存在的文本文件,文件必須存在。

    • "w":寫入模式,用于創(chuàng)建一個新的空文本文件,如果文件已存在,則刪除其內(nèi)容。

    • "a":追加模式,用于打開一個文本文件以便寫入,如果文件不存在,則創(chuàng)建文件,文件指針被放在文件的末尾。

    • "r+":讀寫模式,用于打開一個文本文件用于讀取和寫入,文件必須存在。

    • "w+":讀寫模式,用于創(chuàng)建一個新的空文本文件用于讀取和寫入,如果文件已存在,則刪除其內(nèi)容。

    • "a+":讀寫模式,用于打開一個文本文件用于讀取和寫入,如果文件不存在,則創(chuàng)建文件,文件指針被放在文件的末尾。

  • 返回值:函數(shù)調(diào)用成功時,返回一個指向 FILE 類型對象的指針(FILE *),該指針與打開或創(chuàng)建的文件相關(guān)聯(lián)。后續(xù)的標(biāo)準(zhǔn) I/O 操作將圍繞這個 FILE 指針進(jìn)行。如果函數(shù)調(diào)用失敗,則返回 NULL,并設(shè)置 errno 以指示錯誤原因。


以下是一個簡單的示例,演示了如何使用 fopen() 打開文件:


#include
int main() {    FILE *file_ptr;
   // 以只讀模式打開文件    file_ptr = fopen("example.txt", "r");    if (file_ptr == NULL) {        printf("Failed to open file.n");        return 1;    }
   // 在這里可以進(jìn)行文件讀取操作
   // 關(guān)閉文件    fclose(file_ptr);
   return 0;}



在這個示例中,我們嘗試以只讀模式打開名為 example.txt 的文件。如果文件打開失敗,則會打印一條消息并退出程序。否則,我們可以在之后的代碼中對文件進(jìn)行讀取操作。最后,我們使用 fclose() 函數(shù)關(guān)閉文件,釋放資源。



2.3、fwrite寫文件


fwrite() 是C語言標(biāo)準(zhǔn)庫中用于向文件寫入數(shù)據(jù)的函數(shù)之一。它的原型如下:


size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);


函數(shù)參數(shù)和返回值含義如下:


  • ptr:參數(shù) ptr 是一個指向緩沖區(qū)的指針,該緩沖區(qū)中存儲了要寫入到文件中的數(shù)據(jù)。函數(shù)將會把這個緩沖區(qū)中的數(shù)據(jù)寫入到文件中。

  • size:參數(shù) size 指定了每個數(shù)據(jù)項的字節(jié)大小,即每次寫入的數(shù)據(jù)的大小。

  • nmemb:參數(shù) nmemb 指定了寫入的數(shù)據(jù)項的個數(shù),即要寫入到文件中的數(shù)據(jù)項的數(shù)量。

  • stream:參數(shù) stream 是一個指向 FILE 結(jié)構(gòu)的指針,它標(biāo)識了要寫入數(shù)據(jù)的文件。

  • 返回值:調(diào)用成功時,fwrite() 函數(shù)返回實際成功寫入到文件中的數(shù)據(jù)項的數(shù)目。如果發(fā)生錯誤,則返回值可能小于參數(shù) nmemb(或者等于 0)。

fwrite() 函數(shù)返回成功寫入的數(shù)據(jù)項數(shù)目,如果返回值與 nmemb 不同,則表示寫入出現(xiàn)了錯誤。


以下是一個簡單的示例,演示了如何使用 fwrite() 向文件寫入數(shù)據(jù):


#include
int main() {    FILE *file_ptr;    char buffer[] = "Hello, world!";
   // 打開文件以便寫入    file_ptr = fopen("example.txt", "w");    if (file_ptr == NULL) {        printf("Failed to open file.n");        return 1;    }
   // 向文件寫入數(shù)據(jù)    size_t num_written = fwrite(buffer, sizeof(char), sizeof(buffer), file_ptr);    if (num_written != sizeof(buffer)) {        printf("Failed to write to file.n");        fclose(file_ptr);        return 1;    }
   // 關(guān)閉文件    fclose(file_ptr);
   return 0;}


在這個示例中,我們向文件 "example.txt" 寫入了字符串 "Hello, world!"。首先我們打開文件以便寫入,然后使用 fwrite() 函數(shù)將數(shù)據(jù)寫入文件,最后關(guān)閉文件。


2.4、fread讀文件

fread() 是C語言標(biāo)準(zhǔn)庫中用于從文件讀取數(shù)據(jù)的函數(shù)之一。它的原型如下:


size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);


函數(shù)參數(shù)和返回值含義如下:


  • ptr:fread() 函數(shù)將讀取到的數(shù)據(jù)存放在參數(shù) ptr 指向的緩沖區(qū)中。這個緩沖區(qū)是用來存儲從文件中讀取的數(shù)據(jù)的。

  • size:fread() 函數(shù)從文件讀取 nmemb 個數(shù)據(jù)項,每個數(shù)據(jù)項的大小為 size 個字節(jié)。因此,總共讀取的數(shù)據(jù)大小為 nmemb * size 個字節(jié)。

  • nmemb:參數(shù) nmemb 指定了要讀取的數(shù)據(jù)項的個數(shù)。

  • stream:參數(shù) stream 是一個指向 FILE 結(jié)構(gòu)的指針,它標(biāo)識了要從中讀取數(shù)據(jù)的文件。

  • 返回值:調(diào)用成功時,fread() 函數(shù)返回成功讀取到的數(shù)據(jù)項的數(shù)目。如果發(fā)生錯誤或到達(dá)文件末尾,則返回值可能小于參數(shù) nmemb。由于 fread() 無法區(qū)分文件結(jié)尾和錯誤,返回值小于 nmemb 時,可以使用 ferror() 或 feof() 函數(shù)來進(jìn)一步判斷是發(fā)生了錯誤還是已經(jīng)到達(dá)了文件末尾。



fread() 函數(shù)返回成功讀取的數(shù)據(jù)項數(shù)目,如果返回值與 nmemb 不同,則表示讀取出現(xiàn)了錯誤。


以下是一個簡單的示例,演示了如何使用 fread() 從文件中讀取數(shù)據(jù):


#include
int main() {    FILE *file_ptr;    char buffer[100]; // 緩沖區(qū)用于存儲讀取的數(shù)據(jù)
   // 打開文件以便讀取    file_ptr = fopen("example.txt", "r");    if (file_ptr == NULL) {        printf("Failed to open file.n");        return 1;    }
   // 從文件讀取數(shù)據(jù)    size_t num_read = fread(buffer, sizeof(char), sizeof(buffer), file_ptr);    if (num_read == 0) {        printf("Failed to read from file.n");        fclose(file_ptr);        return 1;    }
   // 輸出讀取的數(shù)據(jù)    printf("Read from file: %sn", buffer);
   // 關(guān)閉文件    fclose(file_ptr);
   return 0;}


在這個示例中,我們打開了一個名為 "example.txt" 的文件以便讀取。我們使用 fread() 函數(shù)從文件中讀取數(shù)據(jù),并將其存儲在名為 buffer 的緩沖區(qū)中。最后,我們打印出讀取到的數(shù)據(jù),并關(guān)閉文件。


2.5、fclose關(guān)閉文件


fclose() 是C語言標(biāo)準(zhǔn)庫中用于關(guān)閉文件的函數(shù)之一。它的原型如下:


int fclose(FILE *stream);


函數(shù)參數(shù)和返回值含義如下:


  • stream:指向 FILE 結(jié)構(gòu)的指針,標(biāo)識要關(guān)閉的文件。

  • 返回值:調(diào)用成功返回 0;失敗將返回 EOF(也就是-1)。


以下是一個示例,演示了如何使用 fclose() 關(guān)閉文件:


#include
int main() {    FILE *file_ptr;
   // 打開文件以便讀取    file_ptr = fopen("example.txt", "r");    if (file_ptr == NULL) {        printf("Failed to open file.n");        return 1;    }
   // 在這里可以進(jìn)行文件讀取操作...
   // 關(guān)閉文件    if (fclose(file_ptr) != 0) {        printf("Failed to close file.n");        return 1;    }
   return 0;}


在這個示例中,我們打開了一個名為 "example.txt" 的文件以便讀取。在文件讀取操作完成后,我們使用 fclose() 函數(shù)關(guān)閉了文件。如果關(guān)閉文件失敗,則會打印一條錯誤消息并退出程序。


*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞: 嵌入式 Linux

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉