国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux系統編程中的文件描述符調用

C語言編程學習基地 ? 來源:博客園 ? 作者:melonstreet ? 2021-09-02 09:50 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

文件描述符

進程每打開一個文件的時候,會獲得該文件的文件描述符,而后續的讀寫操作都把文件描述符作為參數。在用戶空間或者內核空間,都是通過文件描述符來唯一地索引一個打開的文件。文件描述符使用int類型表示,文件描述符的范圍從0開始,到上限值-1,默認情況下,上限值為1024,也就是說,進程默認情況下最多可以打開1024個文件。負數是不合法的文件描述符,當函數調用出錯時,返回的文件描述符為-1。

每個進程都至少包含三個文件描述符:

8c65cdc2-0b7a-11ec-8fb8-12bb97331649.png

遵循Linux一切皆文件的概念,文件描述符除了訪問普通文件外,幾乎能夠訪問任何能夠讀寫的東西。包括設備文件、管道、先進先出緩沖區、套接字等。

open()系統調用

對文件進行讀寫之前,必須先打開文件。Linux提供了系統調用open()。open()有兩個函數原型:

8c6f5fc2-0b7a-11ec-8fb8-12bb97331649.png

兩個函數均可用來打開文件,第二個函數比第一個多了參數mode,mode指定文件的權限---當創建新文件的時候才需要。如果文件打開成功,則返回文件描述符,指向pathname所指定的文件。flags參數用于指定打開的方式,它支持三種訪問模式:

8c7b926a-0b7a-11ec-8fb8-12bb97331649.png

flags參數還可以與下面的值進行按位或運算,修改打開文件的行為:

8c8c4a4c-0b7a-11ec-8fb8-12bb97331649.png

舉個例子,下面的句子表示:以寫的方式打開文件,如果文件不存在,則創建新的文件,并且文件的內容為空:

int fd ;

fd = open("file.txt",O_WRONLY|O_CREAT|O_TRUNC,0644);

這里的0644指定了新創建的文件訪問權限,參數mode的取值如下:

8c97b33c-0b7a-11ec-8fb8-12bb97331649.png

實際上最終寫入磁盤的文件訪問權限是由mode參數和用戶的文件創建掩碼(umask)執行按位與操作得到的。舉個例子:

8ca9a132-0b7a-11ec-8fb8-12bb97331649.png

按理來說,創建出來的文件的訪問權限應該是-rwxrwxrwx,而查看后發現其實不是:

ls -l TEST.txt

-rwxrwxr-x 1 huanzhewu huanzhewu 0 8月 30 21:29 TEST.txt【權限為0775】

查看當前的掩碼:

$ umask

0002

可以發現 0775 = 0777 ^ (~0002) ,所以0775才是最后的文件訪問權限。umask是進程級屬性,通過調用umask()函數來修改,支持用戶修改新創建的文件和目錄的權限。

總結起來可以得到這樣一條公式:

newmode = mode ^ (~ umask)

總結一下:至此,我們了解了文件打開所提供的兩個系統調用函數open(),了解了打開文件的方式、新建文件的訪問權限設置。如果文件打開成功,那么將返回一個文件描述符,這是一個非零整數(因為0,1,2是進行已經擁有的文件描述符),否則函數將返回-1

creat()系統調用

顧名思義,creat函數用來創建一個文件,不過我們可能產生疑問:前面的open函數使用一些選項后,不是也可以創建新文件嗎?沒錯,creat函數完全等價與下面的open語句:

8cb24800-0b7a-11ec-8fb8-12bb97331649.png

由于選項O_WRONLY|O_CREAT|O_TRUNC組合經常使用,因而系統調用專門使用creat函數來提供這個功能。creat函數的原型如下:

8cbdfdb2-0b7a-11ec-8fb8-12bb97331649.png

其中參數的描述與open的參數一致,這里不再贅述。

read()系統調用

文件打開后,就能夠讀文件了。read()是最基礎、最常見的讀取文件的機制。read的函數原型為:

8cd2fe10-0b7a-11ec-8fb8-12bb97331649.png

fd 為文件描述符。每次調用read函數時,會從fd指向的文件的當前偏移(或稱文件位置)開始讀取count字節到buf所指的的內存中。隨著文件的讀取,fd的文件位置指針會向前移動。關于read的讀取,會出現很多需要思考的問題:

問題一:如果文件長度為0

問題二:如果文件長度不夠count長度

問題三:如果讀取時,read被信號中斷了

我們一一來看:

問題1屬于“沒有數據可讀”,此時read調用會阻塞,直到有數據可讀;

問題2屬于到達數據結尾(EOF),此時read調用返回0;

問題三,read調用返回大于0小于count的值;如果在讀取任何數據之前被信號中斷,則返回-1,同時把errno設置為EINTR。

8fdd37ba-0b7a-11ec-8fb8-12bb97331649.png

再來看看問題1,當文件沒有數據可以讀時(一開始就沒有),read調用會被阻塞,直到文件有數據可以讀,這是一種阻塞I/O。如果文件以O_NONBLOCK模式打開,則文件為非阻塞模式,當文件沒有數據可以讀時,read系統調用返回-1,并把errno設置為EAGAIN。

8fe9f2f2-0b7a-11ec-8fb8-12bb97331649.png

除了errno被設置為EINTR與EAGAIN,其他情況下都是出現嚴重的文件讀取錯誤,重新執行讀操作不會成功。

write() 系統調用

write的函數原型為:

9000f858-0b7a-11ec-8fb8-12bb97331649.png

write的返回值比較簡單:

寫入失敗返回-1 ,同時設置errno的值

寫入成功返回成功寫入的字節數。

返回0時沒有特殊含義,僅表示寫入了0個字節的內容。

對于普通文件,write基本能保證每次執行調用能夠寫入全部的內容。對于其他文件如socket,需要進行循環寫,保證所有的字節都寫入了文件中:

9014a24a-0b7a-11ec-8fb8-12bb97331649.png

同樣的,當以非阻塞的模式打開文件時(O_NONBLOCK),系統調用write()會返回-1,并把errno設置為EAGAIN。

系統調用write()時,數據從用戶空間的緩沖區中拷貝到了內核空間的緩沖區,但并沒有立即把數據寫入磁盤中,這稱為延遲寫。延遲寫的問題在于,如果在數據真正寫入磁盤之前系統崩潰了,則數據可能丟失。內核設置了一個時間,在該時間內將內核空間緩沖區上的數據寫入磁盤,該時間稱為"最大存放時效"。Linux系統也支持強制文件立即寫入磁盤上,這在后面介紹。

close()系統調用

程序完成文件的讀寫后,調用close函數關閉文件描述符與文件之間的連接,使得文件描述符可以被重用。close的函數原型為:

#incldue

int close(int fd);

文件關閉成功返回0,出錯返回-1,并設置相應的errno。文件成功關閉并不以為著該文件的數據已經被寫入磁盤。

總結:本文簡單介紹了文件的打開、創建、讀寫、關閉操作,介紹了一些常用的open參數選項,creat與open的等價性,循環讀、循環寫的必要性,也關注了各個系統調用的返回值含義,了解如何設置非阻塞讀寫,并簡單提到了延遲寫的問題,在后續的文件中將介紹同步I/O的內容。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    88

    文章

    11746

    瀏覽量

    218845
  • 編程
    +關注

    關注

    90

    文章

    3716

    瀏覽量

    97088

原文標題:Linux系統編程:基本 I/O 系統調用

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    ElfBoard嵌入式教育科普|Linux系統I/O接口:Open函數詳解

    1.函數概述open()是Linux/Unix內核提供的底層系統調用,核心功能是打開或創建文件。成功調用后,內核會返回一個整型的
    的頭像 發表于 12-29 11:41 ?1026次閱讀
    ElfBoard嵌入式教育科普|<b class='flag-5'>Linux</b><b class='flag-5'>系統</b>I/O接口:Open函數詳解

    飛凌嵌入式ElfBoard-Linux系統文件分類

    的主要功能和Windows系統快捷方式類似,它是指向另一個文件或者目錄,符號鏈接本身不包含數據。6.管道(Pipe)和套接字(Socket)Linux提供了管道和套接字機制,用于不同
    發表于 12-09 08:59

    飛凌嵌入式ElfBoard-文件I/O的深入學習之I/O多路復用

    程序既要讀取鼠標、又要讀取鍵盤,多路讀取。可以采用兩個功能幾乎相同的系統調用來執行I/O多路復用操作,分別是系統調用select和poll
    發表于 12-05 11:18

    飛凌嵌入式ElfBoard-文件I/O的了解探究之復制文件描述符

    。在Linux系統下,可以使用dup或dup2這兩個系統調用文件描述符進行復制。1.dup用于
    發表于 11-26 15:36

    飛凌嵌入式ElfBoard-文件I/O的了解探究之文件的多次打開

    。當調用open函數時,會將文件數據從磁盤等塊設備讀取到內存,內存的這份文件數據就稱為動態文件
    發表于 11-26 15:35

    飛凌嵌入式ElfBoard-文件I/O的了解探究之文件描述符和FILE指針轉換

    在同一個文件上執行I/O操作時,系統I/O與標準I/O可以混合使用,借助于庫函數 fdopen、fileno可以將文件描述符和FILE指針對象之間進行轉換。1.3.3.1 fileno
    發表于 11-20 09:24

    飛凌嵌入式ElfBoard-文件I/O的了解探究之Linux系統文件管理機制

    (Process control block,縮寫PCB)。PCB 數據結構體中有一個指針指向了文件描述符表(File descriptors),文件描述符
    發表于 11-18 08:50

    飛凌嵌入式ElfBoard-系統應用編程文件I/O

    字機制,用于不同進程之間的通信。管道和套接字也被視為文件,并通過文件描述符進行訪問。虛擬文件系統(Virtual File System):虛擬文件
    發表于 10-24 08:57

    STM32H7 ETH rx描述符不可用是怎么回事?

    加入文件系統(掛載在qspi+w25q)后以太網上機會有一段時間ping異常后續正常,去掉這個文件系統以太網就上電正常了 手冊上說eth的dma是獨立的,但是看dma寄存器得知rx描述符無效,期間嘗試關閉cache,情況是不變
    發表于 09-11 07:59

    如何使用 GDMA 描述符模式嗎?

    如何使用 GDMA 描述符模式嗎?
    發表于 08-29 06:00

    如何確定 M483 HSUSB 描述符

    不響應設置地址 USB 1-6:設備不接受地址 7,錯誤 -71” 而BSP的例子和獨立的例子都是為了M487JIDAE, 我無法決定示例的 USB 描述符參數(例如“idProduct”)是否可以用于M483SIDAE?
    發表于 08-28 06:46

    ART-PI H750-USB-MSC設備描述符異常的原因?怎么解決?

    -驗證 2.CubeMX配置 2.1 時鐘配置 2.2 USB配置 2.3 中間件配置 2.4 堆棧配置 3.邏輯分析儀觀察 3.1 主機發送請求設備描述符的SETUP事務階段
    發表于 06-19 06:52

    cx3提示未知的描述符是怎么回事?

    我通過配置生成一個新的工程 運行起來總是提示 未知的描述符
    發表于 06-04 07:08

    將CY7C68013A連接到基板管理控制器 (BMC),讀取設備描述符時發生FX2超時錯誤怎么解決?

    : 使用 ehci-platform 的新高速 USB 設備編號 4 [391.934969] usb 1-1:設備描述符讀取/8,錯誤-110 [397.134834] usb 1-1:設備描述符讀取
    發表于 05-14 07:36

    USB組合設備的配置描述符里一定要用IAD描述符嗎?

    USB組合設備的配置描述符里一定要用IAD描述符
    發表于 03-11 06:41