關于fd和fp(fd:file descirptor fp:file pointor)

通常,我們在輸入數據或輸出數據的設備為鍵盤或者顯示器。當然,我們比較熟悉的輸入輸出,可能就是對于文件的操作,還有直接從終端輸出,顯示到顯示器上。在C語言中,我們使用fopen,fclose,fread,fwrite對文件進行相應的操作。由于操作系統內核的不同,在linux系統下,我們不僅僅可以使用C庫里邊的那些函數,還使用open,close,read,write對文件進行相應的操作,這些都是系統調用的函數。它們之間有聯系也有區別,現在我們分析一下吧。

C庫:

(1)FILE *fopen(const char *path, const char *mode);

(2)int fclose(FILE *fp);

(3)size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

(4)size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

系統調用:

(1)

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);        //flags表示打開的方式,主要有O_RDONLY,O_WRONLY,O_CREAT,O_EXCL等
int creat(const char *pathname, mode_t mode); //如果打開不成功的話,就自己創建一個

我們看出,使用open函數的時候,調用的是系統的函數,而上述fopen是使用C庫里邊的函數。還有一點是open的返回值是整形,這也是與fopen不一樣的。我們使用fopen的時候,它是返回一個file*,在這里,open的返回值是整形,它代表文件描述符。即唯一標識打開文件的信息。文件描述符是什么呢。我們之前在task_struct中介紹過PCB的基本信息。簡單了解了PCB結構體中的信息后,我們發現在task_struct結構體中有一個files_struct結構體就是用于存放打開文件的一系列信息。

struct files_struct {/** read mostly part*/atomic_t count;   //自動增量  bool resize_in_progress;wait_queue_head_t resize_wait;struct fdtable __rcu *fdt;  struct fdtable fdtab;   //文件描述符表/** written part on a separate cache line in SMP*/spinlock_t file_lock ____cacheline_aligned_in_smp;unsigned int next_fd;  //下一個文件描述符unsigned long close_on_exec_init[1]; //執行exec時
需要關閉的文件描述符初值集合  unsigned long open_fds_init[1]; //當前打開文件
的文件描述符屏蔽字  unsigned long full_fds_bits_init[1];struct file __rcu * fd_array[NR_OPEN_DEFAULT]; //指向文件描述符組的指針
};

FILE的結構
struct _iobuf {char *_ptr;          //緩沖區當前指針int   _cnt;char *_base;         //緩沖區基址int   _flag;         //文件讀寫模式int   _file;         //文件描述符int   _charbuf;      //緩沖區剩余自己個數int   _bufsiz;       //緩沖區大小char *_tmpfname;};
typedef struct _iobuf FILE;

可以看到,files_struct中有一個文件描述符表,用來存放文件描述符。我們對于程序啟動時默認會打開三個文件:stdin,stdout,stderr,它們的文件描述符分別表示:0,1,2。頭文件unistd.h中有如下宏:

#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2

總結一下:

每個進程在linux內核中都有一個描述進程信息的結構體,稱為task_struct。而描述進程的信息稱為PCB,每個進程都有自己的PCB(進程控制塊)。在task_struct結構體中,有一個指向files_struct的結構體指針,files_struct結構體中,描述了相應的文件描述符,I/O緩沖區,下一個文件描述符等。

說起庫函數和系統調用,我們知道,最底層是硬件->驅動程序->操作系統->系統調用->shell外殼程序->庫函數->用戶程序;所以可以知道,庫函數是在系統調用的基礎上形成的,因此也知道open與fopen的關系了吧,fopen的底層也是調用了open的。

這里寫圖片描述

同理,看一下另外的read,write,close

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
int close(int fd);

使用這些函數的時候,參數傳入文件描述符來確定是哪個文件。

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

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

相關文章

粗談pragma once與 #ifndef的區別

#ifnde不受編譯器的任何限制&#xff1b; #pragma once不受一些較老的編譯器支持&#xff0c;兼容性不夠好

在mac os10.13系統下 ,將py文件打包成可執行程序后, 里面的路徑出現的問題

本來 用命令行運行py文件, 代碼里面 獲取當前路徑的 語句 例如: os.getcwd() os.path.abspath(__file__) os.path.realpath(__file__)都可以獲取到當前文件的路徑, 但是打包成 可執行程序后, 統統不對了, 變成了 類似 /usr/xxx 的路徑 https://stackoverflow.com/questions/50…

[linux]wait詳解

wait&#xff1a;進程等待 主要有兩種等待方式&#xff1a;阻塞式等待和非阻塞式等待 阻塞式等待&#xff1a;如果子進程正在運行&#xff0c;父進程將會一直等待著子進程運行結束&#xff0c;并且自己什么事都不干 非阻塞式等待&#xff1a;如果子進程正在運行&#xff0c;…

centos 使vim支持+python和+python3

本文為了給ycm服務&#xff0c;不單獨存在。 查看是否支持python vim --version | grep python然后 下載vim8源碼&#xff1a; git clone https://github.com/vim/vim.git 1 進行編譯安裝,添加python3和python2.7的支持&#xff1a; 進入下載的vim的源碼文件夾中&#x…

ffmpeg的學習-00

命令行 大體樣式 ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...有道翻譯的 以后仔細回看 2.描述 ffmpeg是一個非常快的視頻和音頻轉換器&#xff0c;也可以從一個實時音頻/視頻源抓取。它還可以轉換之間的任意采樣…

[Linux]消息隊列

我們知道進程間通信的方法有多種&#xff0c;主要有管道&#xff0c;消息隊列&#xff0c;信號量&#xff0c;共享內存&#xff0c;socket等。之前介紹過管道&#xff0c;今天再介紹一個新的概念–消息隊列。 消息隊列&#xff1a;將一個進程到另一個進程之間發送數據塊的方式…

詳解centos7 YCM YouCompleteMe自動補全安裝,親測成功

文章經重新排版轉移至以下鏈接 https://blog.csdn.net/csdn_kou/article/details/84633663

python 異步與io

文檔地址&#xff1a; https://docs.python.org/zh-cn/3/library/asyncio.html 以后再記錄學習筆記 待續。。。

tornado 學習注意事項--00

設置url匹配的時候&#xff0c; (r/(.*), AMStaticFileHandler,dict(pathos.path.join(current_path, html), default_filenameindex.html))像這種語句要放到最后&#xff0c;因為放到前面的話&#xff0c; 后面的就無法匹配&#xff01;

C++關鍵字速查手冊

[TOC] https://blog.csdn.net/csdn_kou/article/details/81113215 C98關鍵字 C11 關鍵字共73個 alignas alignof用于獲取取指定表達式指定的&#xff08;類似sizeof&#xff0c;可以直接是類型名&#xff09;的對齊(alignment)。alignas用于聲明時指定對齊類似于現有的類型…

[Linux]信號

Linux下的信號是一個什么概念呢。我們在現實生活中也遇到過信號之類的。比如紅綠信號燈&#xff0c;班主任叫你去辦公室并且臉色不好&#xff0c;諸如此類的都會給你一個信號。讓你辨別事情的發生。同樣&#xff0c;Linux下也有許多的信號&#xff0c;讓你執行相應的操作。比如…

怎么用VLC播放器將m3u8鏈接視頻下載到本地

轉載 https://blog.csdn.net/saddyyun/article/details/85245135

【1】C++面試題函數引用重載宏命名空間

函數重載的條件 ? 同一個名字 ? 函數名字相同 ? 參數列表不同 ? 同一個作用域 為什么c支持函數重載而c不支持&#xff1f; c函數名字的修飾規則不一樣。c編譯器對函數修飾規則把int的參數列表形式加了進來&#xff0c;從而保證底層使用不同 cAdd(int a,int b)_AddcA…

[數據結構]Map和Set

說起map和set&#xff0c;想必我們都學過紅黑樹了吧&#xff0c;map和set就是紅黑樹的一個應用領域。它的底層就是由紅黑樹來實現的。下面簡單說一下map和set的使用吧。 首先&#xff0c;有一個栗子是這樣的&#xff0c;讓我們統計出每種水果出現的次數。 我們會想到怎么解決…

js獲取Json對象的長度

有兩種Json形式&#xff1a; 第一種&#xff1a; var json1 {"data":[{"name":"zs","age":"10"}]};對于這種格式的json數據&#xff0c;如果想獲取data的長度&#xff0c;就可以用以下這種方式&#xff1a; var length …

生產者消費者模型(條件變量)

三種關系&#xff1a;互斥&#xff0c;同步&#xff0c;互斥和同步 兩類角色:生產者&#xff0c;消費者&#xff08;線程&#xff09; 一個交易場所&#xff1a;生產者消費者共享的區域 賣蘋果的模型 dish上面只有一個蘋果買家必須要等賣家把蘋果放到dish上才可以去買蘋果。…

linux之信號

信號&#xff1a;在生活中&#xff0c;我們遇到過不同種類的信號&#xff0c;比如&#xff1a;&#xff08;交通信號&#xff0c;乃至某個人的表情&#xff0c;動作等帶給你不同的信號&#xff09;然而&#xff0c;在我們的linux下&#xff0c;我們最熟悉的就是&#xff0c;當遇…

視頻解析有感,在解析 iqiyi與qq視頻的時候,記錄一些發現

最近對iqiyi與qq視頻解析發現&#xff0c;兩個網站的解析流程&#xff0c;尤其是反解析措施 各有特點&#xff0c;簡單記錄一下 先說iqiyi&#xff0c; 瀏覽器模擬移動端可以拿到視頻的mp4鏈接&#xff0c;這個不多說。 iqiyiPC端瀏覽器獲取 ts過程&#xff1a; a.iqiyi一次性…

C語言atoi函數的用法

#include < stdlib.h > int atoi(const char *nptr);用法&#xff1a;將字符串里的數字字符轉化為整形數。返回整形值。 注意&#xff1a;轉化時跳過前面的空格字符&#xff0c;直到遇上數字或正負符號才開始做轉換&#xff0c;而再遇到非數字或字符串結束時(’/0’)才…

[Linux]繼續探究mysleep函數(競態條件)

之前我們探究過mysleep的簡單用法&#xff0c;我們實現的代碼是這樣的&#xff1a; #include<stdio.h> #include<signal.h>void myhandler(int sig) {}unsigned int mysleep(unsigned int timeout) {struct sigaction act,oact;act.sa_handler myhandler;sigempt…