【Linux】基礎 IO(一)

📝前言:

這篇文章我們來講講Linux——基礎IO主要包括:

  1. 文件基本概念
  2. 回顧 C文件的操作
  3. 介紹系統關于文件的基本操作

🎬個人簡介:努力學習ing
📋個人專欄:Linux
🎀CSDN主頁 愚潤求學
🌄其他專欄:C++學習筆記,C語言入門基礎,python入門基礎,C++刷題專欄


目錄

  • 一,基本概念
    • 1. 概念
    • 2. 系統角度
  • 二,C 文件的 IO
    • 1. 打開操作
    • 2. 寫操作
    • 3. 讀操作
    • 4. 默認打開的流
  • 三,系統文件的 IO
    • 1. 位標記傳遞
    • 2 系統調用 open
    • 3 讀寫的系統調用
      • 使用示例
      • 庫函數和系統調用
    • 4 文件描述符(重點)
      • 文件描述符的分配原則

一,基本概念

1. 概念

  • 狹義:
    • 文件在磁盤上
    • 磁盤是永久性存儲物質
    • 磁盤是外設,即是輸入設備,也是輸出設備
    • 對文件的操作,其實是對外設的輸入和輸出,稱為 IO
  • 廣義:
    • Linux 下?切皆文件
    • 文件 == 內容 + 屬性

2. 系統角度

  • 對?件的操作本質是進程對?件的操作
  • 硬件(如磁盤)的管理者是操作系統
  • ?件的讀寫本質不是通過 C 語? / C++ 的庫函數來操作的(這些庫函數只是為用戶提供?便),底層是通過文件相關的系統調用接口來實現的

二,C 文件的 IO

1. 打開操作

fopen

  • FILE *fopen(const char *pathname, const char *mode);
    • pathname:文件路徑
    • mode:打開方式
  • 返回:
    • 成功:返回文件指針
    • 失敗:返回NULL

這個FILE的類型是一個文件結構體,通過typedef來的。這是語言層的。

2. 寫操作

寫操作,在文件不存在的時候都會創建文件。

打開文件時的寫入模式:

  • 清空寫w:清空文件內容,重新寫
  • 追加寫a:在原來文件內容后面追加寫

fwrite

  • size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
    • ptr的數據寫到stream
    • size:每個數據項的大小,比如寫intsiezeof(int)(就是4
    • nmemb:數據項的個數
  • 返回:實際成功寫入的數據項數量

注意:文件寫入的時候不能寫入'\0''\0'是C語言的東西,寫入了以后是亂碼

示例:

  5 // C 語言文件接口回顧6 int main()7 {8     FILE* fp1 = fopen("log1.txt", "w");9     FILE* fp2 = fopen("log2.txt", "a");10     if(fp1 == NULL) printf("log1.txt 打開失敗\n");11     if(fp2 == NULL) printf("log2.txt 打開失敗\n");12     char* str1 = (char *)"測試寫入\n";13     fwrite(str1, strlen(str1), 1, fp1);14     fwrite(str1, strlen(str1), 1, fp2);15     fclose(fp1);16     fclose(fp2);17     return 0;18 } 

當使用相對路徑的時候,進程通過自己記錄的自己工作路徑CWD信息,知道新建的文件要放在哪里

運行結果:
在這里插入圖片描述

3. 讀操作

讀操作,如果文件不存在會報錯
fread

  • size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    • 不解釋了,和fwrite的都一樣,不一樣的就是stream是讀入的流,ptr是存儲讀入數據的地方。
    • 在上一次讀取結束后文件指針的位置繼續讀取。
  • 返回:實際成功讀取的數據項數量

示例:

 20 int main()21 {22     FILE* fp = fopen("log2.txt", "r");23     if(fp == NULL) printf("打開文件失敗");24 25 26     char* str1 = (char *)"測試寫入\n";27     char buff[1024];28     while(1)29     {30         // 這里每次讀都是覆蓋寫buff的,但是我們及時打印出來                                                                                                                                                  31         int s = fread(buff, 1, sizeof(str1), fp); // 這里每次讀一個char,方便后續設置 '\0'32         if(s > 0)33         {34             buff[s] = 0;35             printf("%s", buff);36         }37         if(feof(fp))38             break;39     }40     return 0;41 }

運行結果:
在這里插入圖片描述

4. 默認打開的流

#include <stdio.h>
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;

C默認會打開三個輸?輸出流,分別是標準輸入:stdin, 標準輸出:stdout, 標準錯誤:stderr

三,系統文件的 IO

頭文件:<unistd.h>

1. 位標記傳遞

利用位圖進行標記位傳遞,假設,現有標記位:ONE : 0001TWO:0010THREE:0100

  • 如果我們單獨傳入一個ONE就相當于傳遞了最低位的1
  • 如果我們希望傳遞第最低位的1和次低位的1,就可以傳入ONE | TWO(通過獲的方式)

2 系統調用 open

系統,通過系統調用open打開文件:
在這里插入圖片描述

  • pathname:文件路徑
  • falgs:選項(約等于C語言里面的打開模式),通過 或|來實現傳遞多個選項【這個選項本質是宏實現的標記位】
  • 常見選項:
    • O_RDONLY:只讀打開
    • O_WRONLY: 只寫打開
    • O_RDWR : 讀,寫打開
  • 上面這三個常量,必須指定?個且只能指定?個。
  • 其他選項
    • O_CREAT :若文件不存在,則創建它。需要使用mode選項(傳入3個8進制數字),來指明新文件的訪問權限。如果新建的時候,不傳入,那對應的文件就是亂碼【別忘了實際的權限要考慮umask的影響】
    • O_TRUNC:清空寫
    • O_APPEND:追加寫
  • 返回值
    • 成功:新打開的文件的文件描述符(系統通過這個來找到需要訪問的文件)
    • 失敗:-1

3 讀寫的系統調用

在這里插入圖片描述
write

  • 參數
    • fd:文件描述符
    • buf:指向:要寫入的數據,的緩沖區指針
    • count:要寫入的字節數
  • 返回
    • 成功:實際寫入的字節數
    • 失敗:-1,并設置errno
  • 寫入類型
    • 對于系統而言,沒有什么文本寫入和二進制寫入(這是語言層的概念)
    • 你傳什么指針,他就寫什么,如果你原來數據是一個int a,指針傳&a,則它就是按二進制寫

在這里插入圖片描述
readwrite一樣,只是這里是讀到buf

其余closelseek接口類似C語言

使用示例

以寫入為例:

 45 int main()46 {47     int fd = open("log.txt", O_WRONLY | O_CREAT | O_APPEND, 0666); // 這個打開的效果就相當于 C 語言庫函數的直接 mode 為 a48     const char* str = (char*)"hello world!\n";49     write(fd, str, strlen(str)); // 不寫入 '\0'50     char fd_str[20];51     sprintf(fd_str, "%d\n", fd);  // 轉換為文本52     write(fd, fd_str, strlen(fd_str));53     close(fd);54     return 0;55 } 

通常如果是read,則open就是用帶兩個參數的

運行結果:
在這里插入圖片描述

庫函數和系統調用

  • 語言層的文件結構體FILE里面會存儲文件描述符fd,用于給下層的系統調用傳遞
  • C語言的庫函數fwritefread其實都是對底層系統調用writeread的封裝,在上層為用戶提供便利。
  • C語言的庫函數具有可移植性,但是系統調用沒有
    • 系統調用,如:Linux 的,用的是Linux這一套的。如果把代碼移植到Windows或者其他操作系統就不行了
    • C語言,C的fwritefread是對系統調用的封裝,但是它不只封裝一份操作系統的,它會實現多個操作系統的。后續根據自己在哪個操作系統上使用,通過條件編譯(裁剪),來調用對應的系統接口

4 文件描述符(重點)

什么是文件描述符?
如上圖所展示的 3 就新打開的log.txt的文件描述符
0, 1, 2分別對應 stdin, stdout, stderr

那系統是如何通過文件描述符來找到要訪問的文件的呢?
在這里插入圖片描述

  • 在進程的task_struct里面有一個files指針,指向文件描述表files_struct
  • 在文件描述表中,有fd_array[]指針數組,數組的下標對應著文件描述符,指向對應的文件
  • 而每個文件被描述成一個結構體struct file(類似C語言的FILE),里面存儲著文件的信息

有了文件描述符fd,進程就會在自己的文件描述表里面找對應下標的文件指針,然后就可以訪問對應的文件了。

在這里插入圖片描述

文件描述符的分配原則

files_struct數組當中,找到當前沒有被使用的最小的?個下標,作為新的?件描述符。
比如,一開始有0, 1, 2

  • 直接創建一個新文件,則新文件fd == 3
  • close(1),再創建新文件,則fd == 1

注意:這里的關閉不是真關閉,只是“引用計數 - 1”。

  • 因為一個文件可以同時被多個進程訪問
  • 同一個文件也可以被同一個進程的多個下標指針同時指向。比如stdoutstderr其實都是向顯示器輸出

🌈我的分享也就到此結束啦🌈
要是我的分享也能對你的學習起到幫助,那簡直是太酷啦!
若有不足,還請大家多多指正,我們一起學習交流!
📢公主,王子:點贊👍→收藏?→關注🔍
感謝大家的觀看和支持!祝大家都能得償所愿,天天開心!!!

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

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

相關文章

Java 原生實現代碼沙箱之Java 程序安全控制(OJ判題系統第2期)——設計思路、實現步驟、代碼實現

在看這一期之前&#xff0c;需要先看上一期的文章&#xff1a; Java 原生實現代碼沙箱&#xff08;OJ判題系統第1期&#xff09;——設計思路、實現步驟、代碼實現-CSDN博客 Java 程序可能出現的異常情況 1、執行超時 占用時間資源&#xff0c;導致程序卡死&#xff0c;不釋…

常見的降維算法

作業&#xff1a; 自由作業&#xff1a;探索下什么時候用到降維&#xff1f;降維的主要應用&#xff1f;或者讓ai給你出題&#xff0c;群里的同學互相學習下。可以考慮對比下在某些特定數據集上t-sne的可視化和pca可視化的區別。 一、什么時候用到降維&#xff1f; 降維通常…

理解Yocto項目中`${D}`作為模擬目標系統根文件結構的臨時目錄

在Yocto項目中,理解${D}作為模擬目標系統根文件結構的臨時目錄,可以通過以下具象化的比喻和結構解析來把握其核心邏輯: 一、沙盒模型:構建系統的“實驗場地” ${D}的作用類似于建筑師在施工前搭建的1:1實體模型。它完全模仿目標設備的文件系統布局(如/usr/bin、/etc等目錄…

第十課認識約數

課堂學習&#xff1a; 情景引入&#xff1a; 今天我們來認識一下數學中的約數關系&#xff0c;上節課我們了解完倍數之后就已經對約數有了基本的概念&#xff01; 我們按照是否有余數&#xff0c;可以把他們分成兩類 在整數除法中&#xff0c;如果商是整數沒有余數&#x…

【Vue】vuex的getters mapState mapGetters mapMutations mapActions的使用

目錄 一、getters 二、 mapState 三、 mapGetters 四、 mapMutations 五、 mapActions 學到這兒來個小總結&#xff1a;四個map方法的使用 總結不易~ 本章節對我有很大的收獲&#xff0c; 希望對你也是&#xff01;&#xff01;&#xff01; 本節素材已上傳至Gitee&…

html object標簽介紹(用于嵌入外部資源通用標簽)(已不推薦使用deprecated,建議使用img、video、audio標簽)

文章目錄 HTML <object> 標簽詳解基本語法與核心屬性關鍵屬性解析1. **data**2. **type**3. **width & height**4. **name** 嵌入不同類型的資源1. **嵌入圖像**2. **嵌入音頻**3. **嵌入視頻**4. **嵌入 PDF** 參數傳遞與回退內容**參數&#xff08;<param>&a…

警備,TRO風向預警,In-N-Out Burgers維權風暴來襲

本案是TME律所代理的5月首案&#xff0c;傳奇連鎖快餐品牌In-N-Out Burgers委托維權&#xff01; 案件基本情況&#xff1a; 起訴時間&#xff1a;2025-5-1 案件號&#xff1a;25-cv-04767 品牌&#xff1a;In-N-Out 原告&#xff1a;In-N-Out Burgers 原告律所&#xff…

數據結構算法習題通關:樹遍歷 / 哈夫曼 / 拓撲 / 哈希 / Dijkstra 全解析

已知一棵二叉樹先序遍歷和中序遍歷分別為 ABDEGCFH 和 DBGEACHF&#xff0c;請畫出這個二叉樹的邏輯結構并寫出后序遍歷的序列。 先序遍歷&#xff1a;ABDEGCFH 中序遍歷&#xff1a;DBGEACHF 先序遍歷看出根為A&#xff0c;左子樹DBGE&#xff0c;右子樹CHF A的左子樹 再…

C++GO語言微服務和服務發現

目錄 01 03-go-micro簡介 02 04-服務發現的簡單認識 03 05-consul的安裝 04 06-consul常用的命令 05 07-注冊服務到consul并驗證 06 08-consul健康檢查 07 09-consul結合grpc使用-上&#xff08;只實現grpc遠程調用&#xff09; 08 10-consul結合grpc使用-中&#xff08…

HDFS 常用基礎命令詳解——快速上手分布式文件系統

簡介&#xff1a; 本文面向剛接觸 Hadoop HDFS&#xff08;Hadoop 分布式文件系統&#xff09;的讀者&#xff0c;結合 CSDN 博客風格&#xff0c;系統梳理最常用的 HDFS 客戶端命令&#xff0c;并配以示例和注意事項&#xff0c;幫助你在開發和運維中快速掌握 HDFS 的文件管理…

VUE CLI - 使用VUE腳手架創建前端項目工程

前言 前端從這里開始&#xff0c;本文將介紹如何使用VUE腳手架創建前端工程項目 1.預準備&#xff08;編輯器和管理器&#xff09; 編輯器&#xff1a;推薦使用Vscode&#xff0c;WebStorm&#xff0c;或者Hbuilder&#xff08;適合剛開始練手使用&#xff09;&#xff0c;個…

make和makefile的使用,以及寫一個簡單的進度條程序

1.自動化構建-make/makefile 1.1 背景 一個工程文件中的文件不計其數&#xff0c;其按類型、功能、模塊放在若干目錄中&#xff0c;makefile定義了一系列規則來指定哪些文件需要先編譯&#xff0c;哪些文件需要后編譯&#xff0c;哪些文件需要重新編譯&#xff0c;甚至于過呢…

數據結構中的棧與隊列:原理、實現與應用

前言&#xff1a;棧和隊列是計算機科學中兩種最基礎的線性數據結構&#xff0c;它們的獨特操作規則和廣泛的應用場景使其成為每一位開發者必須掌握的核心知識。本文將通過生活案例、代碼實現和實際應用場景&#xff0c;帶您深入理解這兩種數據結構的精髓。 1.棧&#xff08;Sta…

如何選擇自己喜歡的cms

選擇內容管理系統cms what is cms1.whatcms.org2.IsItWP.com4.Wappalyzer5.https://builtwith.com/6.https://w3techs.com/7. https://www.netcraft.com/8.onewebtool.com如何在不使用 CMS 檢測器的情況下手動檢測 CMS 結論 在開始構建自己的數字足跡之前&#xff0c;大多數人會…

SDC命令詳解:使用all_outputs命令進行查詢

相關閱讀 SDC命令詳解https://blog.csdn.net/weixin_45791458/category_12931432.html all_outputs命令用于創建一個輸出端口對象集合&#xff0c;關于設計對象和集合的更詳細介紹&#xff0c;可以參考下面的博客。 Synopsys&#xff1a;設計對象https://chenzhang.blog.csdn…

vue 中的ref

vue 中的ref vue 中的ref 1. ??ref?? ** 的基本作用** 在 Vue 中&#xff0c;ref 是用來獲取 DOM 元素或者組件實例的一種方式。對于 <el-form> 組件&#xff0c;通過 ref 可以獲取到該表單組件的實例&#xff0c;進而調用表單組件提供的各種方法和訪問其屬性。 …

數據庫版本控制工具--flyway

一. 什么是Flyway Flyway 是一款開源的數據庫遷移工具。它采用簡單直觀的方式管理數據庫變更&#xff0c;通過版本化的遷移腳本確保數據庫結構的一致性和可重復性。無論是開發環境、測試環境還是生產環境&#xff0c;Flyway 都能確保數據庫變更按照預期順序執行&#xff0c;避…

C++使用PoDoFo庫處理PDF文件

&#x1f4da; PoDoFo 簡介 PoDoFo 是一個用 C 編寫的自由開源庫&#xff0c;專用于 讀取、寫入和操作 PDF 文件。它適用于需要程序化處理 PDF 文件的應用程序&#xff0c;比如批量生成、修改、合并、提取元數據、繪圖等。 &#x1f31f; 核心特點 特性說明&#x1f4c4; P…

論文分享? arXiv2025 | TTRL: Test-Time Reinforcement Learning

TTRL: Test-Time Reinforcement Learning TTRL&#xff1a;測試時強化學習 https://github.com/PRIME-RL/TTRL &#x1f4d6;導讀&#xff1a;本篇博客有&#x1f9a5;精讀版、&#x1f407;速讀版及&#x1f914;思考三部分&#xff1b;精讀版是全文的翻譯&#xff0c;篇幅較…

dify插件接入fastmcp示例

文章目錄 1. 使用python完成mcp服務1.1 準備環境&#xff08;python安裝fastmcp&#xff09;1.2 mcp服務端示例代碼1.3 啟動mcp服務端 2. dify接入2.1 安裝MCP SSE和 Agent 策略&#xff08;支持 MCP 工具&#xff09; 插件2.2 dify agent插件配置mcp:2.3 mcp服務配置&#xff…