C庫函數與系統函數

      網友投稿 923 2025-04-03

      C庫函數與系統函數

      1. C庫函數

      2. 虛擬地址空間

      3. 庫函數與系統函數的關系

      4. 系統文件操作相關函數

      4.1 open函數

      4.2 read函數和write函數

      4.3 lseek函數

      4.4 stat 函數

      1. C庫函數

      使用C庫函數會返回一個FILE * 類型的結構體,結構體中包括以下三個部分:

      文件描述符:用來標識文件在磁盤中的位置

      文件讀寫指針位置:讀寫文件過程中指針的實際位置。在文件沒有關閉時,文件指針在末尾,此時想要讀取文件內容,需要用fseek重置文件指針位置到開頭。

      IO緩沖區:保存的是內存地址,通過尋址找到對應的內存塊,以減少對硬盤操作的次數,默認大小為8kb

      eg: 用fgets讀取字符時,先把字符放到緩沖區,當緩沖區存滿時,再把字符通過fputs存入硬盤,而不是一個字符一個字符的操作

      將數據從內存刷新到磁盤的幾種方式

      強制刷新緩沖區:fflush

      緩沖區已滿時

      正常關閉文件

      fclose

      return (main函數)

      exit (main函數)

      2. 虛擬地址空間

      Linux下可執行文件格式:ELF

      Linux下通過命令:file 文件名 查看文件格式

      #define NULL (void*) 0 : 指向的是受保護的地址段

      棧空間分配是從上到下分配

      堆空間分配是從下到上分配

      共享庫:動態庫

      0-3G:用戶區,3G-4G:內核區

      在內核區有一個PCB進程控制塊,里面有一個文件描述符表,實際上是一個數組,有1024個位置(0-1023),每打開一個新的文件,則占用一個文件描述符。

      cpu 為什么要使用虛擬地址空間與物理地址空間映射?解決了什么樣的問題?

      1.方便編譯器和操作系統安排程序的地址分布。程序可以使用一系列相鄰的虛擬地址來訪問物理內存中不相鄰的大內存緩沖區。

      2.方便進程之間隔離。不同進程使用的虛擬地址彼此隔離。一個進程中的代碼無法更改正在由另一進程使用的物理內存。

      3.方便OS使用內存。程序可以使用一系列虛擬地址來訪問大于可用物理內存的內存緩沖區。當物理內存的供應量變小時,內存管理器會將物理內存頁(通常大小為 4 KB)保存到磁盤文件。數據或代碼頁會根據需要在物理內存與磁盤之間移動。

      C庫函數與系統函數

      3. 庫函數與系統函數的關系

      應用層操作0-3G,系統調用操作3G-4G。

      4. 系統文件操作相關函數

      4.1 open函數

      int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);

      打開方式(flags):

      必選項:

      O_RDONLY

      O_WRONLY

      O_RDWR

      可選項:

      O_CREAT

      文件權限: 本地有一個掩碼,用命令umask可查看,可修改:umask 掩碼

      文件的實際權限: 本地掩碼(取反) & 實際的文件權限

      002(取反) & 777 = 775(111111101 & 111111111 = 111111101)

      O_TRUNC:將文件截斷為0,就是將文件清空

      O_EXCL:判斷文件是否存在,與O_CREAT一起使用

      O_APPEND

      #include #include #include //前三個為open()需要包含的頭文件 #include //close() 需要包含的頭文件 #include //exit() #include //perror() #include using namespace std; int main(){ int fd;//定義文件標識符 //打開已有文件 // fd = open("ceshi",O_RDWR); //創建新文件 fd = open("hello.txt",O_RDWR|O_CREAT,0777); if(fd == -1){ perror("open file"); exit(1); } cout << "fd = " << fd << endl; //關閉文件 int ret = close(fd); cout << "ret = " << ret << endl; if(ret == -1){ perror("close file "); exit(1); } return 0; }

      4.2 read函數和write函數

      ssize_t read(int fd, void *buf, size_t count); ssize_t :有符號整型 ssize_t write(int fd, const void *buf, size_t count);

      read 返回值

      -1 讀文件失敗

      0 文件讀寫完畢

      大于0 :讀取的字節數

      #include #include #include #include #include #include //read,write #include using namespace std; int main(){ //打開一個以及存在的文件 int fd = open("hello.txt",O_RDONLY); if(fd == -1){ perror("文件打開失敗"); exit(1); } //創建一個新文件 int fd1 = open("newfile.txt",O_CREAT | O_WRONLY,0777); if(fd1 == -1){ perror("創建失敗"); exit(1); } //讀文件 char buf[2048] = {0}; int count = read(fd,buf,sizeof(buf)); if(count == -1){ perror("讀文件失敗"); exit(1); } while(count){ //將讀出的數據寫入到另一個文件中 int ret = write(fd1,buf,count); cout << "write bytes: " << ret << endl; count = read(fd,buf,sizeof(buf)); } //關閉文件 close(fd); close(fd1); return 0; }

      4.3 lseek函數

      功能:

      獲取文件大小

      移動文件指針

      文件拓展

      #include #include #include #include #include #include #include using namespace std; int main(){ //打開一個以及存在的文件 int fd = open("hello.txt",O_RDWR); if(fd == -1){ perror("文件打開失敗"); exit(1); } //獲取文件大小 int ret = lseek(fd,0,SEEK_END); cout << "文件大小為:" << ret << endl; //文件拓展 ret = lseek(fd,2000,SEEK_END); cout << "ret = " << ret << endl; //實現文件拓展,還需要做一步寫操作 write(fd,"a",1); //關閉文件 close(fd); return 0; }

      4.4 stat 函數

      可使用命令:stat 文件名

      索引節點inode:

      保存的其實是實際的數據的一些信息,這些信息稱為“元數據”(也就是對文件屬性的描述)。

      例如:文件大小,設備標識符,用戶標識符,用戶組標識符,文件模式,擴展屬性,文件讀取或修改的時間戳,鏈接數量,指向存儲該內容的磁盤區塊的指針,文件分類等等。

      ( 注意數據分成:元數據+數據本身 )

      注意inode怎樣生成的

      每個inode節點的大小,一般是128字節或256字節。inode節點的總數,在格式化時就給定(現代OS可以動態變化),一般每2KB就設置一個inode。一般文件系統中很少有文件小于2KB的,所以預定按照2KB分,一般inode是用不完的。所以inode在文件系統安裝的時候會有一個默認數量,后期會根據實際的需要發生變化。

      注意inode號

      inode號是唯一的,表示不同的文件。其實在Linux內部的時候,訪問文件都是通過inode號來進行的,所謂文件名僅僅是給用戶容易使用的。當我們打開一個文件的時候,首先,系統找到這個文件名對應的inode號;然后,通過inode號,得到inode信息,最后,由inode找到文件數據所在的block,現在可以處理文件數據了。

      inode和文件的關系

      當創建一個文件的時候,就給文件分配了一個inode。一個inode只對應一個實際文件,一個文件也會只有一個inode。inodes最大數量就是文件的最大數量。

      功能:獲取文件屬性信息

      函數原型:int stat(const char *pathname, struct stat *statbuf);

      特性:能夠穿透(跟蹤)符號鏈接

      struct stat { dev_t st_dev; //文件的設備編號 ino_t st_ino; //節點 mode_t st_mode; //文件的類型和存取的權限 nlink_t st_nlink; //連到該文件的硬連接數目,剛建立的文件值為1 uid_t st_uid; //用戶ID gid_t st_gid; //組ID dev_t st_rdev; //(設備類型)若此文件為設備文件,則為其設備編號 off_t st_size; //文件字節數(文件大小) blksize_t st_blksize; //塊大小(文件系統的I/O 緩沖區大小) blkcnt_t st_blocks; //塊數 time_t st_atime; //最后一次訪問時間 time_t st_mtime; //最后一次修改時間 time_t st_ctime; //最后一次改變時間(指屬性) };

      Linux 虛擬化

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何利用WORD2003制作中國象棋棋盤(用word怎么制作象棋棋盤)
      下一篇:人力資源的HR系統
      相關文章
      久久精品国产亚洲αv忘忧草 | 亚洲成av人影院| 日本系列1页亚洲系列| 亚洲国产成人精品久久| 亚洲天堂一区二区| 久久亚洲精品成人| 久久亚洲国产伦理| 亚洲AV综合色区无码另类小说| 国产亚洲真人做受在线观看| 亚洲欧洲日产国码av系列天堂| 亚洲人成网站在线播放vr| 亚洲热线99精品视频| 亚洲日韩精品一区二区三区无码 | 亚洲精品国产V片在线观看| 国产成人亚洲精品播放器下载| 久久综合亚洲色hezyo| 在线观看亚洲网站| 亚洲精品国自产拍在线观看| 久久精品国产亚洲Aⅴ香蕉| 国产成人A亚洲精V品无码| 亚洲综合色自拍一区| 久久91亚洲人成电影网站| 亚洲av无码一区二区三区乱子伦 | 久久久亚洲欧洲日产国码农村| 亚洲av无码国产精品色午夜字幕| 亚洲小视频在线观看| 久久精品国产亚洲AV香蕉| 久久亚洲AV成人出白浆无码国产 | 精品亚洲成A人在线观看青青 | 亚洲熟妇色自偷自拍另类| 亚洲三级中文字幕| 亚洲色无码国产精品网站可下载| 亚洲精品精华液一区二区 | 亚洲自偷自拍另类图片二区| 亚洲午夜久久影院| 亚洲国产日韩女人aaaaaa毛片在线| 国产成人精品日本亚洲专| 亚洲精品无码高潮喷水A片软| 成a人片亚洲日本久久| 国产亚洲福利一区二区免费看| 国产偷窥女洗浴在线观看亚洲|