Linux系統層IO

1.c語言文件操作

fopen:打開文件,模式?"w"(寫,覆蓋)或?"r"(讀)。

fwritefwrite(data, size, count, fp),按?size?字節寫入?count?次數據。

freadfread(buf, size, count, fp),返回實際讀取字節數,需結合?feof?處理文件結束。

fclose:關閉文件,釋放資源,必須調用以避免泄漏。

1.打開關閉文件:

#include <stdio.h>int main() {FILE *fp = fopen("myfile", "w");if (!fp) {printf("fopen error!\n");}while (1); // 死循環,fclose無法執行fclose(fp);return 0;
}

2.寫文件:

#include <stdio.h>
#include <string.h>int main() {FILE *fp = fopen("myfile", "w");if (!fp) {printf("fopen error!\n");return 1;}const char *msg = "hello bit!\n";for (int i = 0; i < 5; ++i) { // 更清晰的循環fwrite(msg, strlen(msg), 1, fp);}fclose(fp);return 0;
}

3.讀文件:

#include <stdio.h>
#include <string.h>int main() {FILE *fp = fopen("myfile", "r");if (!fp) {printf("fopen error!\n");return 1;}char buf[1024];const char *msg = "hello bit!\n"; // 正確定義指針(原代碼可能筆誤,此處修正)size_t read_len = strlen(msg); // 12字節while (1) {ssize_t s = fread(buf, 1, read_len, fp); // 每次讀取12字節if (s > 0) {buf[s] = '\0'; // 終止字符串printf("%s", buf);}if (feof(fp)) { // 檢查文件結束break;}}fclose(fp);return 0;
}

更加細節的操作,可以再C語言文件操作-CSDN博客文章中查看

stdin &stdout& stderr

C默認會打開三個輸入輸出流,分別是stdin,stdout,stderr仔細觀察發現,

這三個流的類型都是FILE*,fopen返回值類型,文件指針

2.系統文件I/O

認識一下兩個概念:系統調用和庫函數
上面的 fopen fclose freadfwrite 都是C標準庫當中的函數,我們稱之為庫函數(libc)。
而 open close read write lseek 都屬于系統提供的接口,稱之為系統調用接口

?

不管是c c++ 還是java 所有的語言對文件的操作的庫函數,其實都是系統IO套了一層語言的外殼

2.1.系統文件的接口

1.打開文件open:

打開或創建文件,返回文件描述符。

有兩種創建方式:
第一種:就是文件已經存在的情況

第二種:就是文件如果不存在,那么就其文件進行創建,mode參數就是設置創建文件的權限

1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>4 int open(const char *pathname, int flags);
5 int open(const char *pathname, int flags, mode_t mode);6
7 pathname: 要打開或創建的目標文件
8 flags: 打開文件時,可通過“或”運算組合多個常量,規則如下:
9 參數:
10     基本模式(必選其一,互斥):
11         O_RDONLY:只讀(0)
12         O_WRONLY:只寫(1)
13         O_RDWR  :讀寫(2)
14         三者必選且僅選其一
15     附加標志(可選,| 組合):
16         O_CREAT :創建文件(需配mode,不存在則建,存在則按基本模式打開)
17         O_APPEND:追加寫(指針移到末尾,不覆蓋原有內容)
18         O_TRUNC :寫模式下截斷文件(清空內容,覆蓋寫入,與O_APPEND互斥)
19         O_EXCL   :與O_CREAT聯用,確保文件不存在(存在則失敗,errno=EEXIST,原子創建)
20         O_NONBLOCK:非阻塞IO(設備/套接字操作不阻塞,立即返回,需處理EAGAIN)
21         O_SYNC   :同步寫(數據+元數據立即刷盤,保證持久,性能開銷大)
22         O_DIRECT :直接IO(繞過內核緩沖,需內存/偏移對齊,否則EINVAL)
23 mode: 僅O_CREAT時有效,指定新文件權限(如0644),實際權限為mode & ~umask24 返回值:
25     成功: 非負文件描述符(如3,4...,0/1/2為標準IO)
26     失敗: -1(檢查errno,用perror調試,如ENOENT(文件不存在)、EEXIST(O_CREAT+O_EXCL沖突)等)

2.寫文件write:

向文件寫入緩沖區數據。

3.讀文件read:

關閉文件描述符,釋放資源。

上面三種接口都使到標志位,那么下面就是識別標志位的一種方式:

上面參數flags傳遞標志位的方法:

采用的的位圖的思想,只需要判斷對應的二進制位上是否是1即可

2.1.文件描述符fd

理解文件描述符之前先了解fd代表什么,又是存儲在哪里?

一個進程都有PCB,在PCB中,有個指針數組*files 表示一個進程可以管理多個文件,而指針數組*files 的下標就是我們說的fd ,files[fd]:就是指向下標為fd的文件,系統會自動的的打開三個文件,分別是 標準輸入,標準輸出,標準錯誤,他們對應的下標是 0,1,2

以上原理結論我們可通過內核源碼驗證:

2.1.1.文件描述符的分配規則

在files_struct數組當中,找到 當前沒有被使?的最?的?個下標,作為新的?件描述符
1.沒有將系統自動打開的三個文件關閉,自動排在,下標為三的位置。

2.此時將0和1下標的文件關閉,發現打印的0;

2.1.2.重定向

明白了上面的規則后,看一個現象:

當我們將標準輸出給關閉,printf向輸出文件寫東西的時候,發現內容沒有寫到標準輸出文件,而寫到了新創建的文件

原理:

輸出到了?件 ll?當中,其中,fd=1。這 種現象叫做輸出重定向。常?的重定向有: > , >> , <
也說明了,語言層的庫函數只認fd

使用dup2 系統調用:

函數原型:

再看一個示例:發現此時的fd 和 1指向的都是新創建的ll 文件

3.一切皆文件

首先,在windows中是文件的東西,它們在linux中也是文件;其次一些在windows中不是文件的東西,比如進程、磁盤、顯示器、鍵盤這樣硬件設備也被抽象成了文件,你可以使用訪問文件的方法訪問它們獲得信息;甚至管道,也是文件;


這樣做最明顯的好處是,開發者僅需要使用一套 API和開發工具,即可調取 Linux 系統中絕大部分的資源。舉個簡單的例子,Linux中幾乎所有讀(讀文件,讀系統狀態,讀PIPE)的操作都可以用read 函數來進行;幾乎所有更改(更改文件,更改系統參數,寫PIPE)的操作都可以用 write 函數來進行。

4.緩沖區

緩沖區的定義:

緩沖區是內存空間的一部分。也就是說,在內存空間中預留了一定的存儲空間,這些存儲空間用來緩沖輸入或輸出的數據,這部分預留的空間就叫做緩沖區。緩沖區根據其對應的是輸入設備還是輸出設備,分為輸入緩沖區和輸出緩沖區。

在不同層面上也是分成 :

用戶級:語言層緩沖區

語言層的緩沖區內容就緩沖到文件內核緩沖區

系統層: 文件內核緩沖區

文件內核緩沖區內容就緩沖到磁盤中

緩沖區的作用:

讀寫文件時,如果不會開辟對文件操作的緩沖區,直接通過系統調用對磁盤進行操作(讀、寫等),那么每次對文件進行一次讀寫操作時,都需要使用讀寫系統調用來處理此操作,即需要執行一次系統調用,執行一次系統調用將涉及到CPU狀態的切換,即從用戶空間切換到內核空間,實現進程上下文的切換,這將損耗一定的CPU時間,頻繁的磁盤訪問對程序的執行效率造成很大的影響。


為了減少使用系統調用的次數,提高效率,我們就可以采用緩沖機制。比如我們從磁盤里取信息,可以在磁盤文件進行操作時,可以一次從文件中讀出大量的數據到緩沖區中,以后對這部分的訪問就不需要再使用系統調用了,等緩沖區的數據取完后再去磁盤中讀取,這樣就可以減少磁盤的讀寫次數,再加上計算機對緩沖區的操作大大快于對磁盤的操作,故應用緩沖區可大大提高計算機的運行速度。

這時我們的CPU可以處理別的事情。可以看出,緩沖區就是塊內存區,它用在輸入輸出設備和CPU之間,用來緩存數據。它使得低速的輸入輸出設備和高速的CPU能夠協調工作,避免低速的輸入輸出設備占用CPU,解放出CPU,使其能夠高效率工作。

4.1.緩沖類型

緩沖區類型分成下面三種:
?

全緩沖區:

這種緩沖方式要求填滿整個緩沖區后才進行1/0系統調用操作。對于磁盤文件的操作通常使用全緩沖的方式訪問。

原本標準輸出是行緩沖區,但是已經重定向到了“log.txt”文件,所以變成了全緩沖區,所以要使用語言層的刷新函數fflush進行刷新


行緩沖區:

在行緩沖情況下,當在輸入和輸出中遇到換行符時,標準I/0庫函數將會執行系統調用操作。當所操作的流涉及一個終端時(例如標準輸入和標準輸出),使用行緩沖方式。因為標準I/0庫每行的緩沖區長度是固定的,所以只要填滿了緩沖區,即使還沒有遇到換行符,也會執行/O系統調用操作,默認行緩沖區的大小為1024。

原本標準輸出是行緩沖區,但是已經重定向到了“log.txt”文件,所以變成了全緩沖區,所以沒有數據刷新到文件緩沖區

無緩沖區:

無緩沖區是指標準I/0庫不對字符進行緩存,直接調用系統調用。標準出錯流stderr通常是不帶緩沖區的,這使得出錯信息能夠盡快地顯示出來。

標準錯誤就是無緩沖區:

4.2.FILE

觀察此段代碼:

運行結果1:

運行結果2(對進程實現輸出重定向?./hello > file):

重定向結果解析:

1.當重定向的時候,緩沖區的緩沖方式已經變成了從行緩沖變成了全緩沖。

2.所以msg0和msg1寫在了用戶級的緩沖區,msg3調用的是系統IO,所以直接寫在,內核緩沖區中。

3.fork()創建子進程,所以父子進程都結束的時候,對進行二次對用戶級的緩沖區的刷新

4.所以此時打印的是這種結果

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92555.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92555.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92555.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

QT中的trimmed() 方法(1)

QT中的trimmed() 方法&#xff08;2&#xff09; trimmed() 是 Qt 框架 中 QString 類提供的一個方法&#xff0c;用于 去除字符串首尾的空白字符&#xff08;whitespace characters&#xff09;。它的作用類似于標準 C 中的 std::string 的 trim 操作&#xff0c;但專為 Qt 的…

動漫軟件集合分享

通過網盤分享的文件&#xff1a;動漫軟件 鏈接: https://pan.baidu.com/s/1TD_OmaAZksfFxJ4PW6rS-w?pwd1234 提取碼: 1234 打印動漫.apk 當鳥動漫.apk 動漫共和國【OmoFun復活】.apk 咕咕香.apk 黑貓動漫.apk 團次元【推薦】.apk 橘漫.apk 曼波.apk 萌國.apk 趣動漫.apk 三…

Mysql與Ooracle 索引失效場景對比

MySQL 和 Oracle 作為主流關系型數據庫&#xff0c;其索引失效的場景既有共性&#xff0c;也因底層優化器、索引類型支持等差異存在不同。以下從常見索引失效場景對比兩者的表現及原因&#xff1a;一、索引列上使用函數 / 表達式共性&#xff1a;若直接在索引列上使用函數或表達…

【unity知識】unity使用AABB(軸對齊包圍盒)和OBB(定向包圍盒)優化碰撞檢測

文章目錄前言一、AABB&#xff08;軸對齊包圍盒&#xff09;1、基本概念2、數學表示3、Unity中的實現4、實際應用示例二、OBB&#xff08;有向包圍盒&#xff09;1、Physics.ComputePenetration (Unity 物理引擎)1.1 基本概念1.2 Unity中的實現1.3 實際應用示例2、OBB (SAT) 手…

Numpy科學計算與數據分析專題

Numpy科學計算與數據分析 1. Numpy入門&#xff1a;數組操作與科學計算基礎 2. Numpy入門&#xff1a;多平臺安裝與基礎環境配置 3. Numpy數組創建與應用入門 4. Numpy數組屬性入門&#xff1a;形狀、維度與大小 5. Numpy數組索引與切片入門 6. Numpy數組操作入門&#xff1a;…

齊護機器人小智AI_MCP圖形化編程控制Arduino_ESP32

齊護機器人小智AI_MCP圖形化編程控制Arduino_ESP32 齊護AiTall在項目實踐里&#xff0c;我們常常期望達成這樣一種場景&#xff1a;借助智能體&#xff08;例如小智 AI&#xff09;來遠程操控其他開發板上的設備&#xff0c;這類似于智能家居系統中智能音箱與各類家電的互動模式…

CPO-SVM分類預測+特征貢獻SHAP分析,通過特征貢獻分析增強模型透明度,Matlab代碼實現,引入SHAP方法打破黑箱限制,提供全局及局部雙重解釋視角

代碼功能 該Matlab代碼實現了一個基于CPO-SVM冠豪豬算法優化支持向量機的數據分類模型&#xff0c;結合了SHAP可解釋性分析&#xff0c;CPO選擇最佳的SVM參數c和g。 SVM模型有兩個非常重要的參數C與gamma。其中 C是懲罰系數&#xff0c;即對誤差的寬容度。c越高&#xff0c;說明…

Failed to restart docker.service: Unit docker.service is masked.

docker.service 被標記為 "masked" 意味著 systemd 已阻止該服務被啟動或運行。這通常發生在 Docker Desktop 安裝過程中,因為它使用自己的服務管理機制。以下是解決方法: 解決方案: 解除服務的 mask 狀態: bash sudo systemctl unmask docker.service sudo sys…

2025 藍橋杯C/C++國B 部分題解

P12836 [藍橋杯 2025 國 B] 翻倍 題目描述 給定 nnn 個正整數 A1,A2,…,AnA_1, A_2, \ldots, A_nA1?,A2?,…,An?&#xff0c;每次操作可以選擇任意一個數翻倍。 請輸出讓序列單調不下降&#xff0c;也就是每個數都不小于上一個數&#xff0c;最少需要操作多少次&#xff1f;…

os標準庫

os標準庫os包提供了操作系統函數&#xff0c;但和操作系統無關。 os包的接口規定為在所有操作系統中都是一致的。 設計為Unix風格的。1. 權限說明 os標準庫有大量的文件操作&#xff0c;在創建文件等操作中&#xff0c;需要指的perm。 在go語言中perm是一個uint32類型 在go語言…

QtC++ 中使用 qtwebsocket 開源庫實現基于websocket的本地服務開發詳解

前言 當前實時通信功能越來越受到重視&#xff0c;無論是在線聊天、實時數據監控還是多人協作工具&#xff0c;都離不開高效、穩定的實時通信技術。WebSocket 作為一種全雙工通信協議&#xff0c;為實時通信提供了良好的解決方案。而在 QtC 開發環境中&#xff0c;qtwebsocket …

小程序實時保存優化

背景。避免數據存儲后丟失。要求實時保存。問題&#xff1a;保存時出現卡斷&#xff0c;輸入的內容會被抹除。問題原因。輸入頻繁速度塊&#xff0c;會影響cpu處理速度。解決方案。用戶停止輸入500ms后開始保存&#xff0c;否則不保存。這里是保存方法&#xff1a;當500ms以內有…

國產化Excel處理組件Spire.XLS教程:使用 C# 將 DataTable 導出為 Excel 文件

在 C# 中將 DataTable 導出為 Excel 文件&#xff0c;是 .NET 開發中常見的任務&#xff0c;廣泛應用于報表生成、日志導出、系統間數據共享等場景。通過使用獨立的組件庫&#xff0c;開發者可以輕松將 DataTable 數據寫入 Excel 文件&#xff0c;并應用格式設置&#xff0c;生…

C語言學習筆記——編譯和鏈接

目錄1 C程序的執行流程2 翻譯環境2.1 預編譯2.2 編譯2.2.1 詞法分析2.2.2 語法分析2.2.3 語法分析2.3 匯編2.4 鏈接1 C程序的執行流程 用戶編寫好的C程序不能直接被計算機識別并執行&#xff0c;在執行前&#xff0c;要先將源文件和頭文件進行編譯&#xff0c;生成目標文件&am…

Flink-1.19.0源碼詳解9-ExecutionGraph生成-后篇

《Flink-1.19.0源碼詳解8-ExecutionGraph生成-前篇》前篇已從Flink集群端調度開始解析ExecutionGraph生成的源碼&#xff0c;解析了ExecutionGraph的ExecutionJobVertex節點、ExecutionVertex節點、IntermediateResult數據集、IntermediateResultPartition數據集分區與封裝Task…

19、閾值分割+blob分析

目錄 一、仿射變換 1.變換矩陣 2.在矩陣的基礎上添加各種變換形式 3.開始變換 4.計算變換矩陣參數 新算子 二、閾值分割 新算子 三、blob分析案例 1.焊點 2.石頭 3.木材 4.車牌 5.骰子 新算子 一、仿射變換 1.變換矩陣 // 產生仿射變換矩陣hom_mat2d_identity…

破解 Django N+1 查詢困境:使用 select_related 與 prefetch_related 實踐指南

破解 Django N+1 查詢困境:使用 select_related 與 prefetch_related 實踐指南 開篇引入 數據庫查詢性能常常是 Web 應用性能瓶頸中的重中之重。Django ORM 以簡潔直觀的 API 層將 Python 代碼與數據庫打通,卻也可能因默認的惰性加載帶來 N+1 查詢問題,造成不必要的網絡往…

深入解析K-means聚類:從原理到調優實戰

一、聚類分析與K-means的核心價值在無監督學習領域&#xff0c;聚類分析是探索數據內在結構的核心技術。?K-means算法因其簡潔高效成為最廣泛使用的聚類方法&#xff0c;在客戶分群、圖像壓縮、生物信息學等領域應用廣泛。其核心目標是將數據集劃分為K個簇&#xff0c;實現“簇…

數據結構基礎:哈希表、排序和查找算法

目錄 一、哈希表 1.哈希算法 2.哈希碰撞 3.哈希表 4.哈希表相關操作 哈希表插入 哈希表遍歷 元素查找 哈希表銷毀 二、排序算法 1. 排序算法對比 2. 排序算法實現 冒泡排序 選擇排序 插入排序 希爾排序 快速排序 三、查找算法 1. 查找算法對比 2. 查找算法實…

Linux內核參數調優:為K8s節點優化網絡性能

在高并發微服務環境中&#xff0c;網絡性能往往成為K8s集群的瓶頸。本文將深入探討如何通過精細化的Linux內核參數調優&#xff0c;讓你的K8s節點網絡性能提升30%以上。引言&#xff1a;為什么網絡調優如此重要&#xff1f;作為一名在生產環境中維護過數千節點K8s集群的運維工程…