麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統 > Unix > 正文

《Unix環境高級編程》讀書筆記 第3章-文件I/O

2024-06-28 13:25:00
字體:
來源:轉載
供稿:網友
《Unix環境高級編程》讀書筆記 第3章-文件I/O1. 引言
  • Unix系統的大多數文件I/O只需用到5個函數:open、read、write、lseek以及close
  • 本章描述的函數經常被稱為不帶緩沖的I/O。術語不帶緩沖指的是在用戶的進程中對其不會自動緩沖,每個read和write都調用內核中的一個系統調用。但是,所有磁盤I/O都要經過內核的塊緩存區(也稱為內核的緩沖區高速緩存)。唯一例外的是對原始磁盤設備的I/O。
2. 文件描述符
  • 對于內核而言,所有打開的文件都通過文件描述符引用。文件描述符是一個非負整數,其變化范圍是0~OPEN_MAX-1
  • 慣例:幻數0、1、2分別為符號常量STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO
3. 函數open、openat:創建或打開一個文件
  1. #include <fcntl.h>
  2. int open(const char *path, int oflag, ... /* mode_t mode */ );
  3. int openat(int fd, const char *path, int oflag, ... /* mode_t mode */ );
  4. Both return: file descriptor if OK, −1 on error
  • oflag參數

    1. 以下5個常量必須指定一個且只能指定一個O_RDONLY、O_WRONLY、O_RDWR、O_EXEC(只執行打開)、O_SEARCH(只搜索打開,應用于目錄,尚未支持)
    2. 下列常量則可選O_APPEND、O_CLOEXEC、O_CREAT(需要指定第3個參數mode)、O_EXCL、O_DIRECTORY、O_NOFOLLOW、O_NONBLOCK、O_SYNC、O_TRUNC
  • open和openat函數返回的文件描述符一定是最小的未用描述符數值。這一點被某些應用程序用來在標準輸入、標準輸出或標準錯誤上打開新的文件。

  • fd參數把open和openat函數區分開,共有3種可能性

    1. path參數指定的是絕對路徑名,則fd參數被忽略,openat函數相當于open函數
    2. path參數指定的是相對路徑名,則fd參數指出了相對路徑名在文件系統中的開始地址。fd參數是通過打開相對路徑名所在的目錄來獲取
    3. path參數指定了相對路徑名,而fd參數具有特殊值AT_FDCWD,則路徑名在當前工作目錄中獲取
  • openat函數是POSIX.1最新版本中新增的一類函數之一,希望解決兩個問題:

    1. 讓線程可以使用相對路徑名打開目錄中的文件,而不再只能打開當前工作目錄
    2. 可以避免time-of-check-to-time-of-use(TOCTTOU)錯誤
  • TOCTTOU錯誤的基本思想是:

    指計算機系統的資料與權限等狀態的檢查與使用之間,因為特定狀態在這段時間已發生改變所產生的軟件漏洞

  • 文件名和路徑名截斷

4. 函數creat:創建一個新文件
  1. #include <fcntl.h>
  2. int creat(const char *path, mode_t mode);
  3. Returns: file descriptor opened for write-only if OK, −1 on error
  • 等效于 open( path, O_WRONLY | O_CREAT | O_TRUNC, mode );
  • creat的一個不足之處是它以只寫方式打開所創建的文件
5. 函數close
  1. #include <unistd.h>
  2. int close(int fd);
  3. Returns: 0 if OK, −1 on error
  • 關閉一個文件時會釋放該進程加在該文件的所有記錄鎖
  • 當一個進程終止時,內核自動關閉它所有的打開文件
6. 函數lseek:為一個打開文件設置偏移值
  1. #include <unistd.h>
  2. off_t lseek(int fd, off_t offset, int whence);
  3. Returns: new file offset if OK, −1 on error
  • 每個打開文件(通過open)都有一個與其關聯的“當前文件偏移量”。它通常是一個非負整數(有可能為負),用于度量從文件開始處計算的字節數。
  • offse參數的解釋與whence參數的值有關:SEEK_SET、SEEK_CUR、SEEK_END
  • 若lseek執行成功,返回新的文件偏移量,故可通過 lseek( fd, 0, SEEK_CUR ); 確定當前偏移量
  • 可用來確定所涉及的文件是否可以設置偏移量,管道、FIFO或網絡套接字不可以,lseek返回-1,errno被設置為ESPIPE
  • 名字中的l是在引入off_t類型之前,offset參數和返回值都是long
7. 函數read
  1. #include <unistd.h>
  2. ssize_t read(int fd, void *buf, size_t nbytes);
  3. Returns: number of bytes read, 0 if end of file, −1 on error
  • 讀操作從文件的當前偏移處開始,在成功返回之前,該偏移量將增加實際讀到的字節數
  • 多種情況下使得讀到的字節數少于要求讀的字節數
    1. 讀普通文件時,到達文件尾端
    2. 從終端設備讀時,通常一次最多讀一行
    3. 從網絡讀時,網絡中的緩沖機制可能造成返回值小于所要求讀的字節數
    4. 從管道或FIFO讀時,如若管道包含的字節少于所需的數量,那么read將只返回實際可用的字節數
    5. 從某些面向記錄的設備(如磁帶)讀時,一次最多返回一個記錄
    6. 當一信號造成中斷,而已經讀了部分數據量時
8. 函數write
  1. #include <unistd.h>
  2. ssize_t write(int fd, const void *buf, size_t nbytes);
  3. Returns: number of bytes written if OK, −1 on error
  • 其返回值通常與參數nbytes的值相同,否則表示錯誤。
  • 對于普通文件,寫操作從文件的當前偏移處開始。如果在打開文件時,指定了O_APPEND選項,則在每次寫操作之前,將文件偏移量設置在文件的當前結尾處
9. I/O的效率
  • 大多數文件系統為改善性能都采用某種預讀技術
10. 文件共享
  • 內核使用3種數據結構表示打開文件,它們之間的關系決定了在文件共享方面一個進程對另一個進程可能產生的影響

  • 左邊:進程級的文件描述符表

    1. 文件描述符標志,目前只有一個FD_CLOEXEC
    2. 指向一個文件表項的指針
  • 中間:系統級的打開文件表:每次調用open打開一個文件新增一個文件表項(不同進程可打開同一個文件,導致多個文件表項)

    1. 文件狀態標志(讀、寫、添寫、同步、非阻塞等,受open時指定的oflag參數影響,也可通過fcntl函數指定FD_SETFL改變)
    2. 當前文件偏移量
    3. 指向該文件v節點表項的指針
  • 右邊:文件系統級的i-node表

    1. i節點包含文件的相關信息,如文件的所有者、文件長度、指向文件實際數據塊在磁盤上所在位置的指針等。
    2. linux沒有v節點,而是采用了一個通用i節點。無論是v節點還是通用i節點,它們都是指向一個與文件系統相關的i節點
  • 其他

    1. 完成write之后,文件表項的當前文件偏移量增加所寫入的字節數。如果這導致當前文件偏移量超出了文件長度,則將i節點表項中的當前文件長度設置為當前文件偏移量
    2. 如果通過O_APPEND標志打開一個文件,則相應標志會設置到文件表項的文件狀態標志中。每次執行寫操作之前,當前文件偏移量會首先被設置為i節點表項中的文件長度
    3. lseek函數只修改文件表項中的當前文件偏移量,不進行任何I/O操作。
    4. 注意:文件描述符標志只作用于一個進程的一個文件描述符,而文件狀態標志則作用于指向該文件表項的任何進程中的所有描述符
11. 原子操作
  • 先lseek再write,不等價于,指定了O_APPEND的write
  • 對open函數指定O_CREAT和O_EXCL

  • 函數PRead、pwrite

  1. #include <unistd.h>
  2. ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset);
  3. Returns: number of bytes read, 0 if end of file, −1 on error
  4. ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset);
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久综合久久精品 | 娇喘在线 | 久久久免费观看完整版 | 黄色av网站在线观看 | 99re66热这里只有精品8 | 国产女厕一区二区三区在线视 | 最近日本电影hd免费观看 | 中文字幕在线网站 | 羞羞网站在线观看入口免费 | av色先锋 | 成人三级在线播放 | 毛片118极品美女写真 | 一级做a爱视频 | 羞羞网站在线看 | 久久人人爽人人爽人人片av高清 | sese综合 | 男人天堂免费 | 激情综合在线 | 特级黄色影院 | 久久tv免费国产高清 | 国产亚洲精品综合一区91555 | 日韩精品久久久久久久九岛 | 久久国产精品久久精品国产演员表 | 午夜视频成人 | 欧美成人二区 | 久综合色| 最新欧美精品一区二区三区 | 久久久婷婷一区二区三区不卡 | 黄网站免费在线看 | 欧美成人精品欧美一级 | 国产免费高清在线视频 | a视频在线看 | 亚洲午夜精选 | av手机免费在线观看 | 亚洲黑人在线观看 | 久久精品4 | 毛片一级免费看 | 久久久麻豆 | 羞羞视频免费入口网站 | 美国av在线免费观看 | 二区三区四区视频 |