文件基礎和文件fd

文章目錄

  • 預備知識
  • C語言的文件接口
  • 系統調用
  • 文件fd

正文開始前給大家推薦個網站,前些天發現了一個巨牛的 人工智能學習網站, 通俗易懂,風趣幽默,忍不住分享一下給大家。 點擊跳轉到網站。

預備知識

我們平時說文件就是說文件里面有什么,那么空文件有大小嗎?答案肯定是有的,我們平時所說的文件除了文件的內容以外還存在文件的創建時間,大小等等,這是文件的屬性,所以文件 = 內容 + 屬性的。所以我們對文件的操作無非就是對文件內容或者對文件屬性的操作。不管是內容還是屬性,它們本質都是數據,所以他們被存儲在磁盤中,就是磁盤文件。所以我們要訪問一個文件的時候都是要把這個文件打開的,該文件被打開前就是磁盤文件,被打開后,因為CPU只和內存打交道,所以被打開的文件一定會被加載到內存。所以加載磁盤文件,一定會訪問外設,這部分工作是由OS來做的。
一個進程是可以打開很多文件的,所以進程和文件的比例關系一定是 1 :n 。而在我們的系統中是有很多進程的,所以被打開的文件也可能會非常的多,所以OS要對這些文件進行管理,管理的本質就是先描述在組織,因此在OS中存在struct file結構體來描述文件,所以以后打開一個文件就創建一個file結構體,把他們用鏈表鏈起來,對文件的管理就成了對該鏈表的增刪查改。

C語言的文件接口

C語言打開文件的是fopen
在這里插入圖片描述
第一個參數就是打開文件的名稱,可以使用絕對路徑也可以使用相對路徑,第二個參數是打開的模式,經常用的就是w以寫的方式打開,但是每次打開都會清空文件,不存在就創建,還有一種常用的是a以追加的方式打開,每次打開不會清空文件,直接在文件結尾進行寫入,依然是不存在就創建。還有r方式,是以只讀的方式打開。經常用的就是這三種模式。
我們會發現w模式和我們指令所講的輸出重定向非常像。
在這里插入圖片描述
a模式和追加重定向非常相似。
在這里插入圖片描述

系統調用

我們再來認識一個系統調用open。
在這里插入圖片描述
open函數是一個系統用調用,它的第一個參數就是文件名,和fopen一樣,但是第二個參數是標志位。標志位有很多但是這里我們只介紹常用的幾種。第三個參數是文件的權限,一般來說只有創建文件的時候需要設置。

關于函數傳入標志為的技巧是Linux中常用的傳參方式,接下來給兄弟們演示一下什么叫做標志位傳參。

#include <stdio.h>#define Print1 1
#define Print2 (1 << 1)
#define Print3 (1 << 2)
#define Print4 (1 << 3)void printflag (int flag)
{if(flag & Print1) printf("i am Print1\n");if(flag & Print2) printf("i am Print2\n");if(flag & Print3) printf("i am Print3\n");if(flag & Print4) printf("i am Print4\n");
}
int main()
{printflag(Print1);printf("============================\n");printflag(Print1 | Print2);printf("============================\n");printflag(Print1 | Print2 | Print3);printf("============================\n");printflag(Print1 | Print2 | Print3 | Print4);printf("============================\n");return 0;
}

在這里插入圖片描述
所以open的第二個參數第原理和這個基本上是差不多的,它的選項常用的O_WRONLY(只寫)、O_RDONLY(只讀)、O_CREAT(不存在就創建)、O_TRUNC(每次打開時清空文件)、O_APPEND(追加寫,不清空文件)。open的返回值是一個fd(文件描述符),它是用來表示一個文件的。所以C語言中的FILE也一定封裝了這個數字。有了這些選項的基礎,我們可以來模仿實現一下fopen的各個選項的實現。

FILE _fopen(const char * str, char c)
{int flag = 0;int is_read;if(c == 'a'){flag = O_WRONLY | O_APPEND | O_CREAT;}else{if(c == 'w'){flag = O_WRONLY | O_TRUNC | O_CREAT;}else{if(c == 'r'){flag = O_RDONLY;is_read = 1;}else{//TODO}}}int fd = 0;if(is_read){fd = open(str, flag, 0x666);if(fd < 0){perror("open");exit(-1);} }else{fd = open(str, flag);if(fd < 0){perror("open");exit(-1);} }FILE file;// _fileno就是文件描述符file._fileno = fd;return file;
}

所以C語言的所有庫函數的本質都是封裝了系統調用。

文件fd

到這里我們可以來嘗試理解一下文件了。如何在系統層面上理解一下文件呢?
我們知道每個進程在被創建是都是會有自己的PCB的,在Linux中也就是task_struct,所以每個進程的PCB中都有一個struct files_struct* files 的指針,這個指針指向的結構體中有一個非常重要的一張表,struct file* fd_array[],這是一個指針數組,我們打開的每一個文件都會被在這個指針數組中被指向,一般來說是從小到大來排列的,而數組的下標就是我們上面系統調用返回的文件描述符。所以文件描述符的本質就是數組的下標。操作系統訪問文件只認識文件描述符。
在這里插入圖片描述
我們進程在運行的時候,是會默認打開三個流,標準輸入流、標準輸出流、標準錯誤流。這三個流對應的硬件分別是鍵盤、顯示器、顯示器。因為Linux下一切皆文件,所以這三個流在進程被打開時會一次把文件描述符表的0、1、2位置給占了,所以我們自己打開的文件的fd一般是從3開始從小到大排的。
在這里插入圖片描述
OS默認打開三個流,就是為了我們程序員默認進行輸入輸出的代碼的編寫。

我們如何理解一切接文件?
在file文件中是有函數指針的,所以對于不同的文件我們讓它的文件指針指向對應的方法,如果沒有改方法的話我們讓這個指針指向空就行了,所以在上層看來,文件就是這個方法,但是它是可能對于不同的文件指向的方法也是不同的。
在這里插入圖片描述

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

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

相關文章

1_Springboot(一)入門

Springboot&#xff08;一&#xff09;——入門 本章重點&#xff1a; 1.什么是Springboot; 2.使用Springboot搭建web項目&#xff1b; 一、Springboot 1.Springboot產生的背景 Servlet->Struts2->Spring->SpringMVC&#xff0c;技術發展過程中&#xff0c;對使…

大模型量化技術原理-SmoothQuant

近年來&#xff0c;隨著Transformer、MOE架構的提出&#xff0c;使得深度學習模型輕松突破上萬億規模參數&#xff0c;從而導致模型變得越來越大&#xff0c;因此&#xff0c;我們需要一些大模型壓縮技術來降低模型部署的成本&#xff0c;并提升模型的推理性能。 模型壓縮主要分…

強化學習(六)時序差分

時序差分&#xff08;TD&#xff09;是強化學習的核心&#xff0c;其是蒙特卡羅&#xff08;MC&#xff09;和動態規劃&#xff08;DP&#xff09;的結合。 1、TD 預測 TD 和 MC 都是利用經驗來解決預測問題。一種非平穩環境的一般訪問蒙特卡羅方法是 V ( S t ) ← V ( S t …

Python GUI開發庫之nicegui使用詳解

概要 在 Python 中,創建圖形用戶界面(GUI)應用程序通常需要大量的代碼和時間。然而,隨著 Python 生態系統的不斷發展,出現了一些簡化 GUI 開發過程的工具和庫。其中之一就是 NiceGUI 庫。本文將深入探討 NiceGUI 庫的功能、用法以及如何利用它來創建漂亮而功能豐富的 GUI…

如何使用css實現一個加載動畫

如何使用css實現一個加載動畫 有四個點 初始化為同一個顏色 每個階段 不同的透明度 刷新也不會影響初始化 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthd…

List 集合遍歷過程中刪除元素避坑指南。

文章目錄 1. 遍歷2. 遍歷過程中刪除元素2.1 for 簡單循環正向遍歷方式2.2 for 簡單循環反向遍歷方式2.3 foreach 方式遍歷刪除2.4 Iterator的remove()方法2.5 <font color green> removeIf() &#xff08;推薦&#xff09;<green>2.6 Strem 方式 作為一名后端開發…

python之計算CPI

CPI&#xff0c;即消費者物價指數&#xff08;Consumer Price Index&#xff09;&#xff0c;是一個反映居民家庭一般所購買的消費品和服務項目價格水平變動情況的宏觀經濟指標。它是在特定時段內度量一組代表性消費商品及服務項目的價格水平隨時間而變動的相對數&#xff0c;通…

網絡測試相關

前言 網絡測試通常是指在網絡環境比較復雜&#xff0c;而且有較多限制時&#xff0c;就需要清楚網絡的走向和途徑的節點&#xff0c;便于在出現問題時進行排查和優化網絡性能&#xff0c;相關知識大多是計算機網絡的 測試工具 抓包 wireshark 路由探測 traceroute/tracert 這…

云快充充電樁系統設計書

充電樁系統設計書 一、系統設計概述 隨著新能源汽車市場的快速發展&#xff0c;充電樁作為電動汽車的重要配套設施&#xff0c;其市場需求日益增長。本系統旨在提供一套穩定、高效、易用的充電樁解決方案&#xff0c;以滿足市場上新能源充電樁的主流需求。通過實現云快充V1.6協…

nginx使用詳解--動靜分離

什么是動靜分離&#xff1f; 為了提高網站的響應速度&#xff0c;減輕程序服務器&#xff08;Tomcat&#xff0c;Jboss等&#xff09;的負載&#xff0c;對于靜態資源&#xff0c;如圖片、js、css等文件&#xff0c;可以在反向代理服務器中進行緩存&#xff0c;這樣瀏覽器在請…

如何選擇激活函數?

選擇神經網絡的激活函數是一個重要的決策&#xff0c;因為激活函數的選擇會影響到網絡的收斂速度以及能否有效地訓練。不同的激活函數適用于不同的任務和網絡架構。以下是選擇激活函數時可以考慮的一些指導原則和常用的激活函數&#xff1a; 指導原則 問題類型&#xff1a; 二…

LLM小記

RAG 參考 檢索增強生成(RAG)概念及優化 主流模型 llama系列 1. 背景&#xff1a;模型參數量級的積累&#xff0c;或者訓練數據的增加&#xff0c;哪個對性能提升幫助更大&#xff1f; 最近的 “Training Compute-Optimal Large Language Models” 這篇論文提出一種縮放定…

Java:PDF圖片抽取的兩種方法

圖片和PDF是我們日常生活和工作中經常接觸到的文檔格式。PDF是人們日常使用最多的跨平臺文檔&#xff0c;是一種用獨立于應用程序、硬件、操作系統的方式呈現文檔的文件格式。每個PDF文件包含固定布局的平面文檔的完整描述&#xff0c;包括文本、字形、圖形及其他需要顯示的信息…

如何利用HubSpot海外獲客系統實現海外市場擴張?

在當今全球化的時代&#xff0c;企業面臨著越來越激烈的競爭&#xff0c;而海外市場則被視為獲取更多增長機會的重要途徑之一。針對這一挑戰&#xff0c;企業需要建立一個完整的海外獲客系統&#xff0c;而HubSpot軟件的應用則成為了關鍵。作為HubSpot的合作伙伴&#xff0c;我…

librtmp源碼分析

閱讀了librtmp的源碼&#xff0c;簡單記錄下。 首先補充下AMF格式基本知識 1 AMF格式 AMF是Action Message Format(動作消息格式)的簡寫&#xff0c;它是一種二進制的數據格式。它的設計是為了把actionscript里面的數據(包括Object, Array, Boolean, Number等)序列化成二進制…

jvm 基礎知識和jvm 調優

類裝載分為以下 5 個步驟&#xff1a; 加載&#xff1a;根據查找路徑找到相應的 class 文件然后導入&#xff1b; 檢查&#xff1a;檢查加載的 class 文件的正確性&#xff1b; 準備&#xff1a;給類中的靜態變量分配內存空間&#xff1b; 解析&#xff1a;虛擬機將常量池中的符…

C# 異步返回類型詳解

在現代軟件開發中&#xff0c;異步編程已經成為一種重要的編程范式&#xff0c;尤其是在需要與I/O密集型操作交互的上下文中&#xff0c;比如網絡請求、數據庫操作等。C# 語言提供了強大的異步支持&#xff0c;使得異步編程變得更加簡單和直觀。本文將詳細介紹C#中異步返回類型…

vue3學習 【5】watch的使用

什么是watch 當我們需要根據一個數據的變化來進行一些操作的時候我們需要使用偵聽器&#xff0c;它能夠在響應式數據發生變化的時候觸發提供的回調函數 基礎偵聽 watch 可以偵聽不同的數據源。例如&#xff1a; ref計算屬性響應式對象getter函數多個數據源組層的數據 cons…

20240229金融讀報:央行阿拉善創新融資模式與碳排放權交易條例實施,新春政策聚焦新生產力及金融風險防范

1、人民銀行阿拉善盟分行實例&#xff1a;再貸款產業鏈&#xff08;活體牲畜抵押貸款牲畜死亡率保險&#xff09;、“再貸款新型農牧業經營主體”&#xff08;基礎設施薄弱、產業結構單一&#xff0c;籌集資金創辦嘎查集體經濟股份合作社貸款&#xff09; 2、建設銀行實例&…

oracle11安裝及使用

安裝oracle11 官網下載地址 Oracle Database 11g Release 2 for Microsoft Windows (x64) 官網下載慢可訪問我的資源 也可以網盤獲取 鏈接&#xff1a;https://pan.baidu.com/s/1RDrGkqDA7tfKRnpJXUBMDw 提取碼&#xff1a;z3na 上傳安裝包到服務器 在指定目錄下創建文件…