Linux 基礎IO

文章目錄

  • 前言
  • 基礎IO定義
  • 系統IO接口
  • 文件描述符
  • 重定向原理
  • 緩沖區刷新

前言

要知道每個函數/接口的全部參數和返回值建議去官網或者直接在Linux的man手冊中查,這不是復制粘貼函數用法的文章。
C語言文件讀寫介紹鏈接

基礎IO定義

IO是Input/Output的縮寫,它是計算機領域中常用的術語,用來描述計算機系統與外部設備之間的數據交換過程。輸入(Input)是指將外部數據或指令傳輸到計算機系統中,而輸出(Output)則是指將計算機系統處理后的數據或結果傳輸到外部設備中。例如,鍵盤、鼠標、顯示器、打印機等都屬于外部設備,它們與計算機之間的數據交換過程就是通過輸入和輸出來實現的。

系統IO接口

在說系統IO接口之前需要區分語言庫IO函數和系統IO接口的區別,庫函數IO接口如C語言中的fopen函數 fseek函數 ftell函數 rewind函數 等。這些都是語言庫對系統IO接口open write read close 等IO接口的再封裝。 如圖open write read close 等IO接口在用戶操作接口層,fopen函數 fseek函數 ftell函數 rewind函數 等在用戶層。
在這里插入圖片描述

文件描述符

文件描述簡寫為fd;

在Linux中,每個進程都有一個task_struct, task_struct 里有 *files指針, *files指針指向 files_struct結構體(files_struct結構體內含有file_struct結構體的列表的指針) , fd 是 files_struct 內那個指向的數組 的下標,文件描述符本質是文件信息結構體數組下標。(注意files_structfile_struct 差一個字母 )

在這里插入圖片描述

在調用系統IO接口open打開文件后會返回打開文件描述符。文件描述符是一個非負的整數。在Linux操作系統中的進程中,默認會打開三個文件描述符,分別是0 , 1 , 2 對應三個文件標準輸入文件 標準輸出文件 標準錯誤文件 。(Linux中一切皆文件,硬件如:顯示器,鍵盤鼠標接入后都是Linux系統中的一個個文件)

文件描述符的分配原則是,當一個進程打開新的文件,該文件的信息存放在文件信息存儲數組中未被使用的且素組下標最小的位置。(也就是說如果默認被標準輸入文件使用的0下標在新文件被打開之前就關閉,新文件打開后就會占據0下標來記錄新打開文件的文件信息)
在這里插入圖片描述

重定向原理

重定向原理:關閉文件信息數組newfd下標對應的文件,并將newfd存儲的文件設置為oldfd存儲的文件信息。此時newfd 和 oldfd 文件描述符實際對應的都是重定向之前 newfd對應的文件信息,即可通過newfd 和 oldfd 文件描述訪問同一個文件。

將oldfd實際對應的文件信息給newfd
在這里插入圖片描述重定向使用

使用方法一:利用函數

int dup2(int oldfd, int newfd);

參數:
1.oldfd:一個整數值,表示要復制的舊文件描述符。
2.newfd:一個整數值,表示新的文件描述符。
返回值:
如果成功,返回值為newfd;
如果失敗,返回值為-1,并設置errno來指示錯誤類型。
例:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main() 
{// 打開一個文件用于寫入int fd = open("example.txt", O_WRONLY | O_CREAT, 0644); if (fd == -1) {perror("open");return 1;}// 將標準輸出重定向到文件描述符fd所指向的文件int newfd = dup2(fd, STDOUT_FILENO); if (newfd == -1) {perror("dup2");return 1;}printf("This will be written to example.txt\n"); // 這行內容將會寫入到example.txt文件中close(fd); // 關閉文件描述符fdclose(newfd); // 關閉新的文件描述符newfdreturn 0;
}

使用方法二:在命令行利用重定向符號 < >

在Linux中,重定向符號>用于將命令的輸出結果重定向到指定的文件中。它的作用是將命令的標準輸出(stdout)輸出到文件中,而不是顯示在終端上。
重定向符號>的使用方法是在命令后面加上>符號,緊跟著要輸出到的目標文件名。例如:

command > filename

command表示要執行的命令,filename表示要將輸出結果寫入的目標文件名。
當執行帶有重定向符號>的命令時,如果目標文件已經存在,則會被覆蓋;如果目標文件不存在,則會創建一個新文件。重定向符號>會將命令的標準輸出重定向到目標文件中,不會在終端上顯示輸出結果。以下是幾個示例,演示如何使用重定向符號>進行輸出重定向:

  1. 將ls命令的輸出結果寫入到名為file.txt的文件中:
ls > file.txt
  1. 將command命令的錯誤輸出(標準錯誤流)寫入到名為error.txt的文件中
command 2> error.txt

緩沖區刷新

什么是緩沖區

緩沖區區分

前面IO分為系統IO和語言庫封裝的IO函數,語言庫在封裝IO接口的同時也對IO緩沖區刷新策略做了封裝,C語言的緩沖刷新策略和Linux本身緩沖區刷新策略大致一樣。但C語言的函數在系統緩沖區的基礎上,在語言庫層面(用戶層)再設置了一個緩沖區,該緩沖區具體在FILE結構體中。

Linux 緩沖區刷新策略:

  1. 全緩沖(fully buffered):默認情況下,Linux使用全緩沖模式。在全緩沖模式下,數據會在緩沖區中累積一定量后才會被寫入磁盤,這樣可以減少磁盤I/O操作的次數,提高性能。但是,這也意味著數據可能會在緩沖區中停留一段時間,直到緩沖區滿或者手動刷新。

  2. 行緩沖(line buffered):對于某些特殊的文件,如終端設備,Linux會使用行緩沖模式。在行緩沖模式下,數據會在遇到換行符時立即寫入磁盤,這樣可以保證及時顯示輸出結果。但是,對于普通文件,行緩沖模式并不常見。

  3. 無緩沖(unbuffered):在某些情況下,我們可能需要禁用緩沖區,直接將數據寫入磁盤。這種模式下,數據會立即寫入磁盤,但是由于沒有緩沖區,會導致頻繁的磁盤I/O操作,性能較差。

庫函數刷新策略證明

#include <stdio.h>
#include <string.h>
int main()
{const char *msg0="hello printf\n";const char *msg1="hello fwrite\n";const char *msg2="hello write\n";printf("%s", msg0);fwrite(msg1, strlen(msg0), 1, stdout);write(1, msg2, strlen(msg2));fork();return 0;
}

直接運行結果:

hello printf
hello fwrite
hello write
./test > file 重定向之后結果:
hello write
hello printf
hello fwrite
hello printf
hello fwrite

現象解釋:C語言庫函數緩沖區在輸入對象為終端時刷新策略為行緩沖,直接運行時,在遇到換行符時就將庫函數緩沖區的內容刷新到系統緩沖區,再由系統緩沖區輸入到終端上。重定向后,輸入目標為普通文件,刷新策略變為全緩沖,write輸入到系統緩沖區,fwrite 和 printf 屬于C語言庫函數,輸入了C語言庫函數緩沖區,在子進程創建后,會拷貝一份C語言庫函數緩沖區 (因為拷貝了FILE結構體,C語言庫函數緩沖區即為FILE結構體的成員) 到子進程。 進程結束時會將父子進程C語言庫函數的緩沖區的內容輸入系統緩沖區,再由系統緩沖區一起刷新到終端(屏幕)。

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

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

相關文章

optional

參考資料&#xff1a; Java8 Optional用法和最佳實踐 - 掘金 一、背景 根據Oracle文檔&#xff0c;Optional是一個容器對象&#xff0c;可以包含也可以不包含非null值。Optional在Java 8中引入&#xff0c;目的是解決 NullPointerExceptions的問題。本質上&#xff0c;Optio…

2024年網絡安全競賽-網站滲透

網站滲透 (一)拓撲圖 1.使用滲透機對服務器信息收集,并將服務器中網站服務端口號作為flag提交; 使用nmap工具對靶機進行信息收集 2.使用滲透機對服務器信息收集,將網站的名稱作為flag提交; 訪問頁面即可 3.使用滲透機對服務器滲透,將可滲透頁面的名稱作為flag提交…

Python:核心知識點整理大全5-筆記

目錄 2. 使用方法pop()刪除元素 3. 彈出列表中任何位置處的元素 4. 根據值刪除元素 3 章 列表簡介 3.3 組織列表 3.3.1 使用方法 sort()對列表進行永久性排序 3.3.2 使用函數 sorted()對列表進行臨時排序 3.3.3 倒著打印列表 3.3.4 確定列表的長度 3.5 小結 2. 使用方…

軟件測試:測試用例八大要素模板

一、通用測試用例八要素 1、用例編號&#xff1b; 2、測試項目&#xff1b; 3、測試標題&#xff1b; 4、重要級別&#xff1b; 5、預置條件&#xff1b; 6、測試輸入&#xff1b; 7、操作步驟&#xff1b; 8、預期輸出 二、具體分析通用測試用例八要素 1、用例編號 一般是數字…

[NAND Flash 2.1] NAND Flash 閃存改變了現代生活

依公知及經驗整理&#xff0c;原創保護&#xff0c;禁止轉載。 專欄 《深入理解NAND Flash》 <<<< 返回總目錄 <<<< ? 1989年NAND閃存面世了&#xff0c;它曾經且正在改變了我們的日常生活。 NAND 閃存發明之所以偉大&#xff0c;是因為&#xff0c…

一個CV算法工程師在技術方面的小反思

極市導讀 正如作者所說,做一個算法工程師最重要的素質是在海量的算法方案中理解,吃透那些真正的干貨,然后不斷在實踐中去驗證,并總結吸收到自己的腦子里。本文記錄了作者在算法工程師這個崗位上一年后總結的一些關于技術上的經驗總結。>>加入極市CV技術交流群,走在計…

怎樣解決編譯后的exe文件運行時產生的錯誤?

編譯后的exe文件運行時&#xff0c;錯誤如下錯誤提示&#xff1a;Traceback (most recent call last):File "pd.py", line 1, in <module>from pdf2docx import parse ModuleNotFoundError: No module named pdf2docx 怎樣解決&#xff1f; 這個錯誤提示表明…

java數據結構面試題

1.棧和隊列的共同特點是&#xff08;只允許在端點處插入和刪除元素&#xff09; 4.棧通常采用的兩種存儲結構是&#xff08;線性存儲結構和鏈表存儲結構&#xff09; 5.下列關于棧的敘述正確的是&#xff08;D&#xff09; A.棧是非線性結構 B.棧是一種樹狀結構 C.棧具有先進先…

蘋果OS X系統介紹(Mac OS --> Mac OS X --> OS X --> macOS)

文章目錄 OS X系統介紹歷史與版本架構內核與低級系統圖形&#xff0c;媒體和用戶界面應用程序和服務 特性用戶友好強大的命令行安全性集成與互操作性 總結 OS X系統介紹 OS X是由蘋果公司為Macintosh計算機系列設計的基于UNIX的操作系統。其界面友好&#xff0c;易于使用&…

使用 nohup java - jar 不輸出日志

要在使用nohup java -jar命令時不輸出日志&#xff0c;可以將標準輸出和標準錯誤輸出重定向到特殊設備文件/dev/null。這樣做將會丟棄所有的輸出。 以下是在Linux中使用nohup java -jar命令并禁止輸出日志的示例&#xff1a; 復制代碼 nohup java -jar your-application.jar …

Python可視化(二)——Seaborn

Seaborn是一個基于matplotlib的可視化庫&#xff0c;其為用戶提供了高級接口&#xff0c;并且該工具還深度集成了pandas的數據結構。并且該工具該集成了很多數據庫&#xff0c;配合官網給出的代碼示例&#xff0c;可以更方便的進行操作。 官網對它的介紹為&#xff1a; Seabo…

Servlet學習筆記

簡介 瀏覽器請求處理流程&#xff1a;瀏覽器發請求 > 服務器tomcat( > 應用程序 ( > servlet) ) Servlet應用的三大作用域&#xff1a;request&#xff0c;session&#xff0c;application tomcat存放項目的層級結構 注釋&#xff1a;servlet原引用包名 javax.serv…

卡爾曼濾波器

歡迎訪問我的博客首頁。 卡爾曼濾波器 1. 參考 1. 參考 卡爾曼濾波器&#xff0c;B 站&#xff0c;2020。擴展卡爾曼濾波器&#xff0c;CSDN&#xff0c;2023。

Git的安裝以及SSH配置

前言 近期工作需要&#xff0c;所以版本管理工具要用到Git&#xff0c;某些操作需要ssh進行操作&#xff0c;在某次操作中遇到&#xff1a;git bash報錯&#xff1a;Permission denied, please try again。經排查是ssh沒有配置我的key&#xff0c;所以就借著這篇文章整理了一下…

WorkPlus即時通訊,讓溝通零障礙!企業協作更高效

如今&#xff0c;隨著信息技術的快速發展&#xff0c;企業對于高效溝通和即時協作的需求也日益增長。在這個數字化時代&#xff0c;WorkPlus作為一款領先的企業級移動辦公平臺&#xff0c;以其強大的即時通訊功能和卓越的用戶體驗&#xff0c;成功為企業打造了高效溝通的新時代…

input = torch.randn(20, 2, 11, 11, 32)輸出形式

input torch.randn(20, 2, 11, 11, 32) m torch.nn.AdaptiveAvgPool3d((1,1, 32)) xm(input) print(x.shape) 結果&#xff1a; 也就是不用管批次和通道數

pico示波器使用

文章目錄 Pico示波器保存波形Pico示波器錄制數據Pico示波器解析CAN報文Pico示波器保存波形 Pico示波器可以通過以下步驟保存波形: 在示波器上選擇要保存的波形。連接示波器到計算機上,可以使用USB或者Ethernet連接。打開PicoScope軟件,選擇“File”菜單,然后選擇“Save As…

Python開發運維:Python垃圾回收機制

目錄 一、理論 1.Python垃圾回收機制 一、理論 1.Python垃圾回收機制 &#xff08;1&#xff09;引?計數器 1&#xff09;環狀雙向鏈表 refchain 在python程序中創建的任何對象都會放在refchain鏈表中。 name "david" age 20 hobby ["籃球",游泳…

放蘋果 .

把m個同樣的蘋果放在n個同樣的盤子里&#xff0c;允許有的盤子空著不放&#xff0c;問共有多少種不同的分法&#xff1f; 注意&#xff1a;如果有7個蘋果和3個盤子&#xff0c;&#xff08;5&#xff0c;1&#xff0c;1&#xff09;和&#xff08;1&#xff0c;5&#xff0c;1&…

spring集成mybatis簡單教程

首先說下實現了什么效果&#xff0c;就是不用每次查詢前手動創建 sessionFactory和添加datasource文件了。 整個工程結構是這樣的 這次我也把代碼放在了gitee上&#xff0c;方便大家更全貌的看到所有的實現細節。代碼鏈接如下&#xff1a; Java: 一些Java代碼 (gitee.com) …