中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

電子商務(wù)自助建網(wǎng)站百度入口提交

電子商務(wù)自助建網(wǎng)站,百度入口提交,e京汕頭第一網(wǎng),搭建企業(yè)網(wǎng)站🎬 個(gè)人主頁(yè):誰(shuí)在夜里看海. 📖 個(gè)人專欄:《C系列》《Linux系列》《算法系列》 ?? 道阻且長(zhǎng),行則將至 目錄 📚前言:一切皆文件 📚一、C語(yǔ)言的文件接口 📖1.文件打…

🎬?個(gè)人主頁(yè):誰(shuí)在夜里看海.

📖?個(gè)人專欄:《C++系列》《Linux系列》《算法系列》

???道阻且長(zhǎng),行則將至


目錄

📚前言:一切皆文件?

📚一、C語(yǔ)言的文件接口

📖1.文件打開(kāi)

🔖語(yǔ)法

🔖本質(zhì)

🔖示例

📖2.文件讀取

🔖語(yǔ)法

🔖示例

📖3.文件寫(xiě)入

🔖語(yǔ)法

🔖示例

📖4.文件關(guān)閉

🔖語(yǔ)法

🔖作用

📖5.默認(rèn)流指針

📚二、系統(tǒng)調(diào)用接口

📖1.文件打開(kāi)

🔖語(yǔ)法

🔖示例

📖2.文件讀取

🔖語(yǔ)法

🔖示例

📖3.文件寫(xiě)入

🔖語(yǔ)法

🔖示例

📖4.文件關(guān)閉

🔖語(yǔ)法

📚三、底層調(diào)用&上層封裝

📖1.底層調(diào)用

📖2.上層封裝

🔖3.示例

?4.總結(jié)?

📚四、文件描述符fd

📖1.工作原理

🔖示例

📖2.分配原則

📚五、重定向

📖1.常見(jiàn)的重定向

📖2.本質(zhì)

📖3.dup2系統(tǒng)調(diào)用

🔖語(yǔ)法?

🔖示例

📚六、總結(jié)


📚前言:一切皆文件?

在正式開(kāi)始文件操作的介紹之前,我們先來(lái)解決一個(gè)問(wèn)題,什么是文件?

我們常見(jiàn)的文件有:文本文件(如.txt,.cpp),二進(jìn)制文件(如編譯后的可執(zhí)行文件),圖像文件等等,我們和這些文件打交道,無(wú)非就是對(duì)文件寫(xiě)入和對(duì)文件讀取,然而我們是怎么實(shí)現(xiàn)對(duì)文件的寫(xiě)入和讀取的呢?其實(shí)操作系統(tǒng)為我們提供了這一切,我們告訴系統(tǒng)要訪問(wèn)哪個(gè)文件,調(diào)用系統(tǒng)提供的方法,就實(shí)現(xiàn)了對(duì)文件的操作。

但文件的概念并不僅僅局限于磁盤(pán)上的存儲(chǔ)內(nèi)容,在操作系統(tǒng)中,幾乎所有資源都可以通過(guò)類似“文件”的方式來(lái)進(jìn)行訪問(wèn)和操作。無(wú)論是硬盤(pán)上的數(shù)據(jù),還是連接計(jì)算機(jī)的外設(shè)設(shè)備,操作系統(tǒng)都通過(guò)類似文件的機(jī)制來(lái)統(tǒng)一管理他們。這是操作系統(tǒng)設(shè)計(jì)的一個(gè)重要思想——一切皆文件。

在這個(gè)框架下,設(shè)備(如鍵盤(pán)、鼠標(biāo)、網(wǎng)絡(luò)接口、內(nèi)存等)不再是與文件不同的資源,而是被抽象為一種特殊類型的文件,通過(guò)統(tǒng)一的系統(tǒng)調(diào)用接口,我們可以像操作普通文件那樣,操作這些設(shè)備,這種設(shè)計(jì)方式使得我們能夠以一種一致的方式訪問(wèn)硬件資源。

下面我們來(lái)介紹操作系統(tǒng)具體是如何對(duì)文件進(jìn)行操作,以及如何以“文件”的方式管理各種設(shè)備的。

📚一、C語(yǔ)言的文件接口

任何對(duì)文件的操作都可以看成對(duì)數(shù)據(jù)的訪問(wèn)、讀取和寫(xiě)入,系統(tǒng)為我們提供了這些操作的接口,下面我們就來(lái)看看C語(yǔ)言下的文件接口:

📖1.文件打開(kāi)

🔖語(yǔ)法

C語(yǔ)言提供了標(biāo)準(zhǔn)庫(kù)函數(shù) fopen()?用于打開(kāi)文件:

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

① 參數(shù)1:filename,表示文件名,指定要打開(kāi)的文件路徑,可以是絕對(duì)路徑也可以是相對(duì)路徑

② 參數(shù)2:mode,文件打開(kāi)模式,指定打開(kāi)文件的方式(文件操作的權(quán)限),常見(jiàn)的有:

? ? ?"r",只讀方式打開(kāi)文件,文件必須存在

? ? ?"w",只寫(xiě)方式打開(kāi)文件,文件不存在則創(chuàng)建,存在則清空文件

? ? ?"a",追加模式,文件不存在則創(chuàng)建,存在則數(shù)據(jù)追加到文件末尾

? ? ?"rb",以二進(jìn)制模式讀取文件

? ? ?"rw",以二進(jìn)制模式寫(xiě)入文件

③ 返回值類型:FILE*,文件指針,用于標(biāo)記當(dāng)前打開(kāi)的文件

🔖本質(zhì)

fopen文件訪問(wèn)其實(shí)是做了以下工作:

1. 定位當(dāng)前文件

我們打開(kāi)一個(gè)文件的本質(zhì)其實(shí)是向系統(tǒng)申請(qǐng)指定文件的描述符(FILE*指針),通過(guò)這個(gè)描述符系統(tǒng)就能定位文件,才能完成后續(xù)的讀寫(xiě)操作。所以對(duì)文件操作之前一定要先打開(kāi)文件(其實(shí)就是獲取文件描述符

在C語(yǔ)言中,文件描述符以指針的形式存在,FILE * 是一個(gè)指向文件對(duì)象的指針,它是一個(gè)結(jié)構(gòu)體,內(nèi)部包含了文件操作的狀態(tài)(如文件位置、訪問(wèn)模式等)。

2.設(shè)置文件訪問(wèn)模式

打開(kāi)文件時(shí),需要指定文件的“訪問(wèn)模式”(如讀取、寫(xiě)入、追加等),這告訴操作系統(tǒng)你希望如何使用文件:是否允許讀取文件內(nèi)容,是否可以修改文件,文件是否追加數(shù)據(jù),如果文件不存在是否需要?jiǎng)?chuàng)建。

3.定位文件指針

當(dāng)文件被打開(kāi)時(shí),操作系統(tǒng)會(huì)初始化一個(gè)文件指針指示文件中當(dāng)前可以進(jìn)行讀寫(xiě)操作的位置。在文件讀取或?qū)懭霑r(shí),文件指針會(huì)根據(jù)操作而前進(jìn)或后退。例如,當(dāng)你讀一個(gè)文件時(shí),文件指針會(huì)向前移動(dòng),直到讀到文件的末尾(EOF)。當(dāng)你寫(xiě)一個(gè)文件時(shí),文件指針通常會(huì)向文件的結(jié)尾移動(dòng),或者在追加模式下繼續(xù)從文件的末尾寫(xiě)入。?

🔖示例
    FILE *fp = fopen("myfile", "w");if(!fp){printf("fopen error!\n"); // 訪問(wèn)失敗返回空指針}

這里以"w"只寫(xiě)的方式打開(kāi)"myfile"文件(文件不存在則創(chuàng)建,存在則清空),并返回一個(gè)文件指針,?如果該文件沒(méi)有寫(xiě)權(quán)限時(shí),打開(kāi)失敗,返回空指針。

📖2.文件讀取

🔖語(yǔ)法

C語(yǔ)言提供了標(biāo)準(zhǔn)庫(kù)函數(shù) fread() 用于讀取文件數(shù)據(jù)到緩沖區(qū)中:

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

① 參數(shù)1:ptr,指向存儲(chǔ)讀取數(shù)據(jù)的緩沖區(qū)的指針,讀取的數(shù)據(jù)會(huì)存放到該緩沖區(qū)

② 參數(shù)2:size,讀取的單個(gè)數(shù)據(jù)元素的大小(單位為字節(jié))

③ 參數(shù)3:count,讀取的元素個(gè)數(shù)

④ 參數(shù)4:stream,文件指針(FILE *,就是前面 fopen 的返回值)?

⑤ 返回值類型:size_t,返回成功讀取的元素個(gè)數(shù)(count)

🔖示例
#include <stdio.h>
#include <stdlib.h>int main() {FILE *fp = fopen("numbers.dat", "rb");if (fp == NULL) {perror("Error opening file");return 1;}int numbers[100];size_t elementsRead = fread(numbers, sizeof(int), 100, fp);if (elementsRead != 100) {if (feof(fp)) {printf("Reached end of file.\n");} else {perror("Error reading file");}}for (size_t i = 0; i < elementsRead; i++) {printf("%d ", numbers[i]);}printf("\n");fclose(fp);return 0;
}

fread() 這里用于讀取 numbers.dat 文件的100個(gè)整數(shù),如果文件中少于100個(gè)整數(shù),fread() 會(huì)讀取到文件結(jié)束,并返回實(shí)際讀取的文件個(gè)數(shù)。

使用 feof() 檢查文件是否到達(dá)文件末尾,到達(dá)返回1,否則返回0。

📖3.文件寫(xiě)入

C語(yǔ)言提供了標(biāo)準(zhǔn)庫(kù)函數(shù) fwrite()?用于文件寫(xiě)入,與 fread() 相對(duì)應(yīng):

🔖語(yǔ)法
ssize_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);

① 參數(shù)1:ptr,指向?qū)懭霐?shù)據(jù)指針,可以是數(shù)組、結(jié)構(gòu)體、字符串等

② 參數(shù)2:size,寫(xiě)入的單個(gè)數(shù)據(jù)元素的大小(單位為字節(jié))

③ 參數(shù)3:count,寫(xiě)入的元素個(gè)數(shù)

④ 參數(shù)4:stream,文件指針(FILE *,就是前面 fopen 的返回值)?

⑤ 返回值類型:size_t,返回成功寫(xiě)入的元素個(gè)數(shù)(count)

可以看出 fwrite() 和 fread() 的函數(shù)構(gòu)造是一樣的。

🔖示例
#include <stdio.h>
#include <stdlib.h>int main() {FILE *fp = fopen("numbers.dat", "wb");if (fp == NULL) {perror("Error opening file");return 1;}int numbers[] = {1, 2, 3, 4, 5};size_t elementsWritten = fwrite(numbers, sizeof(int), 5, fp);if (elementsWritten != 5) {perror("Error writing file");}fclose(fp);return 0;
}

fwrite() 將整數(shù)數(shù)組 numbers 中的5個(gè)整數(shù)寫(xiě)入文件 number.dat,如果寫(xiě)入的元素個(gè)數(shù)小于預(yù)期,程序會(huì)打印錯(cuò)誤信息

??注意:

寫(xiě)入文件時(shí)必須使用 "wb" 或 "w" 模式打開(kāi)文件;使用 "wb" 或 "w" 打開(kāi)文件時(shí),會(huì)清空文件的現(xiàn)有內(nèi)容(如果文件已經(jīng)存在)。如果你希望追加數(shù)據(jù),而不是覆蓋原文件,可以使用 "a" 或 "ab"模式打開(kāi)文件。

📖4.文件關(guān)閉

fclose() 函數(shù)用于關(guān)閉 fopen() 打開(kāi)的文件,并釋放文件的資源。關(guān)閉文件后,不能再通過(guò)該文件指針訪問(wèn)文件內(nèi)容:

🔖語(yǔ)法
#include <stdio.h>int fclose(FILE *stream);

① 參數(shù):stream,指向FILE對(duì)象的指針,表示要關(guān)閉的文件

② 返回值類型:int,關(guān)閉成功返回0,失敗返回 EOF,可以通過(guò) perror() 獲取錯(cuò)誤信息。

🔖作用

1.沖刷緩沖區(qū):如果文件是以寫(xiě)方式打開(kāi)的,fclose() 會(huì)保證緩沖區(qū)的數(shù)據(jù)被刷新到磁盤(pán),如果有任何未寫(xiě)入的數(shù)據(jù),都會(huì)被寫(xiě)入目標(biāo)文件。

2.釋放資源:關(guān)閉文件后,操作系統(tǒng)會(huì)釋放與該文件相關(guān)的資源(例如文件描述符)。這對(duì)于防止資源泄漏非常重要。

3.文件指針失效:文件關(guān)閉后,文件指針不再有效。若再次訪問(wèn)該指針,將導(dǎo)致未定義行為。

📖5.默認(rèn)流指針

fopen()返回的文件指針我們又稱之為文件流指針,因?yàn)槲募举|(zhì)上是一個(gè)數(shù)據(jù)流,它可以從文件中讀取數(shù)據(jù),也可以向文件中寫(xiě)入數(shù)據(jù)。在這種抽象下,文件操作就像處理一個(gè)數(shù)據(jù)流,而文件流指針則是指向這個(gè)流的一個(gè)句柄。

在C語(yǔ)言中,有三個(gè)默認(rèn)的文件流指針,分別指向標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出,使得我們無(wú)需顯式地打開(kāi)文件即可進(jìn)行常見(jiàn)的文件操作:

stdin 是標(biāo)準(zhǔn)輸入流,指向鍵盤(pán)輸入,可以使用 scanf() 從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù),也可以通過(guò)這個(gè)流指針,將鍵盤(pán)輸入的數(shù)據(jù)存儲(chǔ)到磁盤(pán)文件中;

stdout 是標(biāo)準(zhǔn)輸流,指向終端或控制臺(tái),可以使用 printf() 將數(shù)據(jù)輸出到標(biāo)準(zhǔn)輸出,也可以通過(guò)流指針將磁盤(pán)文件內(nèi)容輸出到標(biāo)準(zhǔn)輸出中;

#include <stdio.h>#include <string.h>int main(){const char *msg = "hello fwrite\n";fwrite(msg, strlen(msg), 1, stdout);printf("hello printf\n");fprintf(stdout, "hello fprintf\n");return 0;}

stderror 是標(biāo)準(zhǔn)錯(cuò)誤流,用于輸出錯(cuò)誤信息。也指向終端或控制臺(tái)。

📚二、系統(tǒng)調(diào)用接口

在操作系統(tǒng)中,文件操作不僅僅是通過(guò)標(biāo)準(zhǔn)庫(kù)函數(shù)如 fopen(), fread(), fwrite(), 和 fclose() 實(shí)現(xiàn)的,還可以通過(guò)系統(tǒng)調(diào)用接口直接進(jìn)行。系統(tǒng)調(diào)用提供了低級(jí)別、直接的操作系統(tǒng)資源訪問(wèn)方式,包括對(duì)文件的操作。這些系統(tǒng)調(diào)用通常用于底層編程,它們繞過(guò)標(biāo)準(zhǔn)庫(kù)函數(shù),直接與操作系統(tǒng)內(nèi)核交互

📖1.文件打開(kāi)

在 Linux 系統(tǒng)中,文件的打開(kāi)操作是通過(guò)系統(tǒng)調(diào)用 open() 完成的。open() 函數(shù)會(huì)返回一個(gè)文件描述符(而不是 FILE* 指針),這是操作文件的基礎(chǔ):

🔖語(yǔ)法
int open(const char *pathname, int flags, mode_t mode);

① 參數(shù)1:pathname,文件路徑,指定要打開(kāi)的文件。

② 參數(shù)2:flags,指定文件的打開(kāi)模式,如:

? ? ?O_RDONLY:只讀模式

? ? ?O_WRONLY:只寫(xiě)模式

? ? ?O_RDWR:讀寫(xiě)模式

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

? ? ?O_APPEND:追加模式

③ 參數(shù)3:mode,文件的默認(rèn)權(quán)限設(shè)置,僅在創(chuàng)建新文件時(shí)有效,通常為0644權(quán)限位:

? ? ?0表示當(dāng)前數(shù)字為八進(jìn)制,我們?cè)谠O(shè)置權(quán)限時(shí),要考慮三類用戶:所有者所有組以及其他用戶

? ? ?644表示所有者權(quán)限為可讀可寫(xiě)不可執(zhí)行,所有組和其他用戶僅可讀,不可寫(xiě)不可執(zhí)行。

④ 返回值:int,打開(kāi)成功時(shí)返回一個(gè)非負(fù)整數(shù),表示文件描述符;打開(kāi)失敗返回-1。int類型的文件描述符和FILE*指針作用一樣,都可以指向文件,前者可以看作數(shù)組下標(biāo),后者作為指針指向。

🔖示例
#include <fcntl.h>
#include <unistd.h>int main()
{    int fd1 = open("myfile_1", O_RDONLY); // mode可缺省int fd2 = open("myfile_2", O_WRONLY, 0664);
}

📖2.文件讀取

系統(tǒng)調(diào)用 read()?用于從已打開(kāi)的文件描述符中讀取數(shù)據(jù):

🔖語(yǔ)法
ssize_t read(int fd, void *buf, size_t count);

① 參數(shù)1:fd,文件描述符,通過(guò) open() 獲取。

② 參數(shù)2:buf,緩沖區(qū),存儲(chǔ)讀取的數(shù)據(jù)。

③ 參數(shù)3:要讀取的字節(jié)數(shù)。

④ 返回值:ssize_t,成功時(shí),返回實(shí)際讀取的字節(jié)數(shù);失敗時(shí),返回 -1(所以這里不能使用size_t作為返回值,而是ssize_t)

🔖示例
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(){int fd = open("myfile", O_RDONLY);if(fd < 0){perror("open");return 1;}const char *msg = "hello bit!\n";char buf[1024];while(1){ssize_t s = read(fd, buf, strlen(msg));//類比writeif(s > 0){printf("%s", buf);}else{break;}}close(fd);return 0;}

📖3.文件寫(xiě)入

系統(tǒng)調(diào)用 write() 用于將數(shù)據(jù)寫(xiě)入文件:

🔖語(yǔ)法
ssize_t write(int fd, const void *buf, size_t count);
🔖示例
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(){umask(0);int fd = open("myfile", O_WRONLY|O_CREAT, 0644);if(fd < 0){perror("open");return 1;}int count = 5;const char *msg = "hello bit!\n";int len = strlen(msg);while(count--)write(fd, msg, len);close(fd);return 0;}

?umask()是Linux中設(shè)置權(quán)限掩碼的系統(tǒng)調(diào)用,用于控制文件創(chuàng)建的默認(rèn)權(quán)限,調(diào)用 umask(0) 將文件創(chuàng)建掩碼設(shè)置為 0,意味著沒(méi)有權(quán)限被去除,系統(tǒng)會(huì)允許最大權(quán)限的創(chuàng)建。

如果調(diào)用 umask(002),則創(chuàng)建的文件會(huì)去掉 2 (即 0002),那么文件權(quán)限將變成 664,目錄權(quán)限將變成 775,即去除其他用戶的寫(xiě)權(quán)限。

📖4.文件關(guān)閉

系統(tǒng)調(diào)用 close() 用于關(guān)閉打開(kāi)的文件描述符,釋放相關(guān)資源:

🔖語(yǔ)法
int close(int fd);

① 參數(shù):fd,文件描述符,通過(guò) open() 獲取。

② 返回值:int,成功時(shí),返回 0;失敗時(shí),返回 -1?。

作用與fclose相同,也是沖刷緩沖區(qū)以及釋放資源。

📚三、底層調(diào)用&上層封裝

?C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)與系統(tǒng)調(diào)用函數(shù)都可以實(shí)現(xiàn)對(duì)文件的訪問(wèn)操作,那么它們之間有什么關(guān)聯(lián)呢?

?C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)是對(duì)系統(tǒng)調(diào)用的上層封裝

📖1.底層調(diào)用

底層調(diào)用即系統(tǒng)調(diào)用,是操作系統(tǒng)提供的接口,允許用戶程序與操作系統(tǒng)內(nèi)核進(jìn)行交互。當(dāng)程序需要進(jìn)行文件操作時(shí),實(shí)際上是通過(guò)調(diào)用操作系統(tǒng)內(nèi)核提供的系統(tǒng)調(diào)用接口完成的,常見(jiàn)的系統(tǒng)調(diào)用接口有 open(), write(), read(), close() 等,這些系統(tǒng)調(diào)用直接與操作系統(tǒng)的文件系統(tǒng)進(jìn)行交互。

📖2.上層封裝

C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù) fopen(), fread(), fwrite(), fclose()?是對(duì)操作系統(tǒng)提供的系統(tǒng)調(diào)用的封裝,它們提供了更高層次的接口,使得使用者不需要直接與操作系統(tǒng)底層交互,能夠更便捷地進(jìn)行文件操作。標(biāo)準(zhǔn)庫(kù)函數(shù)內(nèi)部實(shí)現(xiàn)了文件描述符的管理、緩沖區(qū)的操作等,屏蔽了底層的細(xì)節(jié)。

🔖3.示例

open() 是一個(gè)系統(tǒng)調(diào)用,直接與操作系統(tǒng)交互,返回一個(gè)文件描述符。這個(gè)文件描述符可以用于進(jìn)一步的 read()、write() 等操作。其實(shí)現(xiàn)較為底層,涉及操作系統(tǒng)的文件系統(tǒng)和內(nèi)存管理。

fopen() 是 C 語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù),它的內(nèi)部實(shí)現(xiàn)使用了 open() 系統(tǒng)調(diào)用來(lái)打開(kāi)文件。除了 open()fopen() 還管理了緩沖區(qū)的初始化等工作,簡(jiǎn)化了文件操作過(guò)程。fopen() 返回的是一個(gè)文件指針(FILE*),它在標(biāo)準(zhǔn)庫(kù)內(nèi)部使用該指針來(lái)進(jìn)行文件操作,而不是直接暴露文件描述符。

?4.總結(jié)?

特性系統(tǒng)調(diào)用 open() / read() / write()系統(tǒng)調(diào)用 open() / read() / write()
功能直接與操作系統(tǒng)交互,底層文件操作提供高層接口,封裝底層系統(tǒng)調(diào)用
返回值文件描述符(int)文件指針(FILE*
管理緩沖區(qū)不負(fù)責(zé)緩沖區(qū)管理自動(dòng)管理文件緩沖區(qū)(提高效率)
使用難度較低層,涉及操作系統(tǒng)管理較高層,易于使用,屏蔽底層細(xì)節(jié)
適用場(chǎng)景需要精細(xì)控制文件操作的底層程序一般的文件操作,簡(jiǎn)潔高效的接口

📚四、文件描述符fd

文件描述符(File Descriptor,簡(jiǎn)稱fd)是操作系統(tǒng)用來(lái)表示已打開(kāi)文件的整數(shù)。它是系統(tǒng)用來(lái)跟蹤打開(kāi)文件的標(biāo)識(shí)符,與標(biāo)準(zhǔn)流、系統(tǒng)調(diào)用的接口密切相關(guān)。

📖1.工作原理

每當(dāng)程序調(diào)用 open() 函數(shù)打開(kāi)一個(gè)文件,操作系統(tǒng)會(huì)為該文件分配一個(gè)文件描述符。文件描述符是一個(gè)非負(fù)整數(shù),用于在后續(xù)的系統(tǒng)調(diào)用中標(biāo)識(shí)該文件。

操作系統(tǒng)通常會(huì)為每個(gè)進(jìn)程維護(hù)一個(gè)文件描述符表,其中每個(gè)文件描述符對(duì)應(yīng)一個(gè)打開(kāi)的文件或設(shè)備。在 Linux 系統(tǒng)中,文件描述符通常從 0 開(kāi)始分配。0、1、2 是系統(tǒng)默認(rèn)的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出流,而其他文件描述符則用于指向程序顯式打開(kāi)的文件。

?

🔖示例
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>int main() {int fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("Error opening file");return 1;}// 使用文件描述符fd讀取文件內(nèi)容char buffer[100];ssize_t bytesRead = read(fd, buffer, sizeof(buffer));if (bytesRead > 0) {write(1, buffer, bytesRead);  // 輸出到標(biāo)準(zhǔn)輸出}close(fd);  // 關(guān)閉文件描述符return 0;
}

在這個(gè)例子中,程序通過(guò) open() 獲取文件描述符 fd,然后用 read() 讀取文件內(nèi)容,最后用 close() 關(guān)閉文件描述符。文件描述符 fd 在操作系統(tǒng)內(nèi)部對(duì)應(yīng)于打開(kāi)的文件或設(shè)備,操作系統(tǒng)會(huì)根據(jù)它來(lái)執(zhí)行讀取操作。

📖2.分配原則

文件描述符的分配原則是怎么樣的呢?來(lái)看看下面這段代碼:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(){int fd = open("myfile", O_RDONLY);if(fd < 0){perror("open");return 1;}printf("fd: %d\n", fd);close(fd);return 0;}

此時(shí)fd是3,如果我將0或者2關(guān)閉呢:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(){close(0);//close(2);int fd = open("myfile", O_RDONLY);if(fd < 0){perror("open");return 1;}printf("fd: %d\n", fd);close(fd);return 0;}

發(fā)現(xiàn)此時(shí)fd為0(或者2),由此可以得到文件描述符fd的分配原則:

在files_struct數(shù)組當(dāng)中,找到當(dāng)前沒(méi)有被使用的 最小的一個(gè)下標(biāo),作為新的文件描述符。?

📚五、重定向

重定向(Redirection)是操作系統(tǒng)提供的一種機(jī)制,允許將程序的輸入和輸出從默認(rèn)設(shè)備(通常是終端或控制臺(tái))重定向到其他設(shè)備或文件。重定向通常通過(guò)操作系統(tǒng)提供的文件描述符來(lái)實(shí)現(xiàn)。

例如還是上面那段代碼,我們關(guān)閉1:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>int main(){close(1);int fd = open("myfile", O_WRONLY|O_CREAT, 00644);if(fd < 0){perror("open");return 1;}printf("fd: %d\n", fd);fflush(stdout);close(fd);exit(0);}

此時(shí)我們發(fā)現(xiàn),本應(yīng)該輸出到顯示器上的內(nèi)容輸出到了文件myfile中,其中fd=1,這種現(xiàn)象叫做輸出重定向。常見(jiàn)的重定向有:>, >>, <:

📖1.常見(jiàn)的重定向

🔖> (輸出重定向):

功能: 將命令的標(biāo)準(zhǔn)輸出重定向到一個(gè)文件中。如果目標(biāo)文件已經(jīng)存在,則會(huì)覆蓋文件內(nèi)容。

echo "Hello, World!" > output.txt

這會(huì)將 "Hello, World!" 輸出到 output.txt 文件中,覆蓋文件原有內(nèi)容。

🔖>> (追加輸出重定向):

功能: 將命令的標(biāo)準(zhǔn)輸出追加到文件末尾。如果目標(biāo)文件不存在,則會(huì)創(chuàng)建文件。

echo "New line of text" >> output.txt

這會(huì)將 "New line of text" 追加到 output.txt 文件的末尾。

🔖< (輸入重定向):

功能: 將文件的內(nèi)容作為標(biāo)準(zhǔn)輸入傳遞給命令。

sort < input.txt

這會(huì)將 input.txt 文件的內(nèi)容傳遞給 sort 命令進(jìn)行排序。

這三種重定向符號(hào)是最常見(jiàn)的,用于控制數(shù)據(jù)流向文件或從文件讀取數(shù)據(jù)。在復(fù)雜的腳本或命令行操作中,它們非常有用,能夠幫助用戶將輸出存儲(chǔ)到文件中或從文件中讀取數(shù)據(jù)。

📖2.本質(zhì)

重定向的本質(zhì)是改變數(shù)據(jù)流的方向,每個(gè)文件描述符(如 0, 1, 2)都關(guān)聯(lián)一個(gè) file_struct(文件結(jié)構(gòu)體)。當(dāng)進(jìn)行重定向操作時(shí),操作系統(tǒng)需要首先清空當(dāng)前文件描述符的相關(guān)信息,然后修改文件描述符的指向,例如將2重定向到1時(shí):?

① 清除?2 指向的文件結(jié)構(gòu)體內(nèi)容;

② 修改 2 的指向,使其指向?1 所指向的文件結(jié)構(gòu)體內(nèi)容。

📖3.dup2系統(tǒng)調(diào)用

dup2 是一個(gè)用于文件描述符復(fù)制的系統(tǒng)調(diào)用,它的作用是將一個(gè)現(xiàn)有的文件描述符復(fù)制到另一個(gè)文件描述符上,替換掉目標(biāo)文件描述符原有的內(nèi)容。

🔖語(yǔ)法?
int dup2(int oldfd, int newfd);

① oldfd:源文件描述符,表示要復(fù)制的現(xiàn)有文件描述符;

② newfd:目標(biāo)文件描述符,表示復(fù)制到該文件描述符。如果該文件描述符已經(jīng)打開(kāi),則它會(huì)被關(guān)閉,然后復(fù)制 oldfd 的內(nèi)容。

🔖示例
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>int main()
{int fd = open("./tmp.txt", O_RDWR|O_CREAT, 0664);if (fd < 0)return -1;dup2(fd, 1);printf("i like linux!\n");return 0;
}

這里我們將標(biāo)準(zhǔn)輸出重定向到文件tmp.txt中,執(zhí)行結(jié)果:

📚六、總結(jié)

在 C 語(yǔ)言中,標(biāo)準(zhǔn)庫(kù)函數(shù)提供了較高層次的抽象,使得文件操作變得簡(jiǎn)便易用。我們通過(guò) fopen() 打開(kāi)文件,利用 fread()fwrite() 進(jìn)行讀寫(xiě)操作,并通過(guò) fclose() 關(guān)閉文件。這些操作的實(shí)現(xiàn)背后,實(shí)際上是依賴于操作系統(tǒng)提供的低級(jí)系統(tǒng)調(diào)用,如 open()、read()、write()close()這些系統(tǒng)調(diào)用直接與操作系統(tǒng)內(nèi)核進(jìn)行交互,提供了更精細(xì)的控制。

通過(guò)對(duì)比系統(tǒng)調(diào)用與標(biāo)準(zhǔn)庫(kù)函數(shù)的使用場(chǎng)景,我們可以更清楚地理解它們各自的優(yōu)勢(shì)和適用范圍。標(biāo)準(zhǔn)庫(kù)函數(shù)封裝了底層細(xì)節(jié),適合一般的文件操作,而系統(tǒng)調(diào)用則提供了更低層次、更精細(xì)的操作,適合需要高性能和底層控制的場(chǎng)景。


以上就是【文件操作的藝術(shù)——從基礎(chǔ)到精通】的全部?jī)?nèi)容,歡迎指正~?

碼文不易,還請(qǐng)多多關(guān)注支持,這是我持續(xù)創(chuàng)作的最大動(dòng)力!??

http://www.risenshineclean.com/news/40134.html

相關(guān)文章:

  • 品牌展板設(shè)計(jì)制作seo免費(fèi)軟件
  • 網(wǎng)站被模仿如何維權(quán)青島seo整站優(yōu)化哪家專業(yè)
  • ps企業(yè)網(wǎng)站模板免費(fèi)下載百度網(wǎng)盤(pán)官方
  • 重慶企業(yè)網(wǎng)站推廣公司合肥網(wǎng)
  • 羅湖中心區(qū)做網(wǎng)站怎么樣建一個(gè)網(wǎng)站
  • 廣州設(shè)計(jì)公司網(wǎng)站廣告營(yíng)銷案例100例
  • 網(wǎng)站開(kāi)發(fā)費(fèi)入什么費(fèi)用中國(guó)十大企業(yè)培訓(xùn)公司
  • 國(guó)外做美食視頻網(wǎng)站有哪些寧波seo外包服務(wù)
  • 柳市網(wǎng)站托管西安網(wǎng)站制作建設(shè)
  • 河池建設(shè)銀行招聘網(wǎng)站百度推廣客服投訴電話
  • 溫州網(wǎng)站設(shè)計(jì)定制市場(chǎng)營(yíng)銷最有效的手段
  • mvc5網(wǎng)站開(kāi)發(fā)之美電子版可靠的網(wǎng)站優(yōu)化
  • dnf怎么做提卡網(wǎng)站谷歌網(wǎng)站收錄提交入口
  • 山東網(wǎng)站排行免費(fèi)的關(guān)鍵詞優(yōu)化軟件
  • 自己做pc網(wǎng)站建設(shè)愛(ài)站網(wǎng)挖掘詞
  • 哪些企業(yè)需要網(wǎng)站建設(shè)的微信客戶管理系統(tǒng)
  • 網(wǎng)站建設(shè)時(shí)如何建立客戶信賴感杭州seo排名
  • 做網(wǎng)站mfdos泰州網(wǎng)站排名seo
  • 網(wǎng)頁(yè)建設(shè)類有哪些軟件seo小白入門(mén)教學(xué)
  • 時(shí)時(shí)彩網(wǎng)站怎么建設(shè)關(guān)鍵詞優(yōu)化百家號(hào)
  • WordPress用戶發(fā)表插件廣州seo排名收費(fèi)
  • 做此廣告的網(wǎng)站推廣公司產(chǎn)品
  • 網(wǎng)站建設(shè)做軟件開(kāi)發(fā)嗎大型網(wǎng)站制作
  • 網(wǎng)站開(kāi)發(fā)編程html網(wǎng)頁(yè)設(shè)計(jì)模板
  • 網(wǎng)站建站 免費(fèi)運(yùn)營(yíng)網(wǎng)站
  • 本地wordpress 固定連接優(yōu)化模型有哪些
  • 怎么做淘寶優(yōu)惠券的網(wǎng)站杭州10大軟件開(kāi)發(fā)公司
  • 人民日?qǐng)?bào)客戶端的視頻怎么下載seo全網(wǎng)圖文推廣
  • 企業(yè)網(wǎng)站seo優(yōu)幫云無(wú)限制訪問(wèn)國(guó)外的瀏覽器
  • 做甜點(diǎn)的網(wǎng)站百度手機(jī)seo軟件