第九周(11.02-11.08)学习笔记
一、學習目的
二、學習資源
三、學習方法
三、學習任務
1 .閱讀教材,注意每個系統調用的參數、返回值,會查幫助文檔
完成課后練習(書中有參考答案)重點:10.1、10.2、10.3、10.4、10.5
2 .重要命令:
man -k key1 | grep key2| grep 2 : 根據關鍵字檢索系統調用
grep -nr xxx /usr/include :查找宏定義,類型定義。
四、學習過程
第十章 系統級I/O
10.1 Unix I/O
1.打開文件
一個應用程序通過要求內核打開相應文件,來宣告它想要訪問一個I/O設備。
Unix外殼創建時都有三個打開的文件
標準輸入、標準輸出、標準錯誤。
頭文件<unistd.h> 定義了常量: STDIN_FILENO STDOUT_FILENO STDERR_FILENO2.改變當前的文件位置
對于每個打開的文件,內核保持著一個文件位置k,初始為0。應用程序通過執行seek操作,顯示的設置文件的當前位置為k.
3.讀寫文件
一個讀操作就是從文件拷貝n>0個字節到儲存器,從當前文件位置k開始,讓后將k增加到k+n.
4.關閉文件
當應用完成了對文件的訪問之后,它就通知內核關閉這個文件。
10.2打開和關閉文件
1、打開文件:
進程是通過調用open函數來打開一個已存在的文件或者創建一個新文件:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(char *filename, int flags, mode_t mode); //返回:若返回成功則為新文件描述符,若出錯為-1。flags 參數指明了進程打算如何訪問這個文件:
O_RDONLY: Reading only
O_WRONLY: Writing only
O_RDWR: Reading and writing
flags參數也可以是一個或者更多位掩碼的或,提供一些額外的指示:
O_CREAT: 如果文件不存在,就創建它的一個截斷的(空)文件。
O_TRUNC:如果文件已經存在,就截斷它。
O_APPEND:再每次寫操作前,設置文件位置到文件的結尾處。
2、關閉文件
#include <unistd.h> int close(int fd);10.3 讀和寫文件
3、讀文件
應用程序是通過分別調用read和write函數來執行輸入和輸出的。
read函數從描述符為fd的當前文件位置拷貝最多n個字節到儲存器位置buf。
返回值-1表示一個錯誤,而返回值0表示EOF。否則,返回值表示的時實際傳送的字節數量。
include <unistd.h>ssize_t read(int fd, void *buf, size_t n);//返回:若成功則為0,若出錯則為-1.4、寫文件
write函數從儲存器位置buf拷貝至多n個字節到描述符fd到當前位置。
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t n);
//返回:若成功則為寫的字節數,若出錯則為-1.讀時遇到EOF
假設該文件從當前文件位置開始只含有20個字節,而應用程序要求我們以50個字節的片進行讀取,這樣一來,這個read的返回的值是20,在此之后的read則返回0.
從終端讀文本行
如果打開的文件是與終端相關聯的,那么每個read函數將一次傳送一個文本行,返回的不足值等于文本行的大小。(具體的含義可看我以前的文章,關于緩沖區的)
讀和寫網絡套接字(socket)
如果打開的文件對應于網絡套接字,那么內部緩沖約束和較長的網絡延遲會導致read和write返回不足值。
10.4 用Rio包健壯地讀寫
RIO的無緩沖的輸入輸出函數
通過調用rio _ readn和rio _ writen函數,應用程序可以在存儲器和文件之間直接傳送數據。
#include "csapp.h"ssize_t rio_readn(int fd,void *usrbuf,size_t n);ssize_t rio_writen(int fd,void *usrbuf,size_t n);若成功則返回傳送成功的字節數若EOF則為0(只對rio_readn而言),若出錯 則為-1RIO的帶緩沖的輸入函數
rio _ readlineb和rio _ readnb函數從一個內部讀緩沖區拷貝一個文本行,當緩沖區變空時,會自動調用read重新填滿緩沖區。
void rio_readinitb(rio_t *rp,int fd);(無返回)ssize_t rio_readlineb(rio_t *rp,void *usrbuf,size_t maxlen);ssize_t rio_readnb(rio_t *rp,void *usrbuf,size_n); (若成功則返回傳送成功的字節數,若EOF則為0,若出錯 則為-1)打開每一個描述符都會調用一次rio _ readinitb函數,他將描述符fd和地址rp處的一個類型為rio _ t的讀緩沖區聯系起來。
帶緩沖的函數的調用不應該和無緩沖的rio _ readn交叉使用。
10.5 讀取文件元數據
應用程序能通過調用stat和fstat函數,檢索到關于文件的信息(元數據)。stat函數以一個文件名作為輸入,fstat函數以文件描述符作為輸入。
#include <unistd.h> include <sys/stat.h>int stat(const char *filename,struct stat *buf); int fstat(int fd,struct stat *buf);st _ size成員包含了文件的字節數大小。st _ mode成員則編碼了文件訪問許可位和文件類型。
普通文件包括某種類型的二進制或文本數據。
目錄文件包含關于其他文件的信息。
套接字是一種用來通過網絡與其他進程通信的文件。
10.6 共享文件
內核用三個相關的數據結構來表示其打開的文件。
描述符表:表項由進程打開的文件描述符來索引的,每個打開的描述符表指向文件表中的一個表項,每個進程有其獨立的描述符表。
文件表:打開文件的集合是由一張文件表來表示的,所有的進程共享這張表。包括:當前的文件位置、引用計數、以及一個指向v-node表中對應表項的指針。
v-node表:每個表項包含stat結構中的大多數信息,;包括st_mode和st_size成員,所有進程共享。
10.7 I/O重定向
I/O重定向操作符,允許用戶將磁盤文件和標準輸入輸出聯系起來。
dup2函數拷貝描述符表表項oldfd到描述符表項newfd,覆蓋描述符表表項newfd以前的內容。如果newfd已經打開,dup2會在拷貝oldfd之前關閉newfd。
#include <unistd.h>int dup2(int oldfd,int newfd);10.8 標準I/O
標準I/O庫將一個打開的文件模型化為一個流,也就是一個指向FILE類型的結構的指針。
#include <stdio.h> extern FILE *stdin; /*標準輸入,文件描述符為0*/ extern FILE *stdout; /*標準輸出,文件描述符為1*/ extern FILE *stderr; /*標準錯誤,文件描述符為2*/類型為file的流是對文件描述符和流緩沖區的抽象,目的是使開銷較高的Unix I/O系統調用的數量盡可能小。
遇到問題
- 第一次嘗試使用Markdown不是很熟練,但是感覺很強大
- 所謂"截斷"是什么意思
- csapp.h 不識別
轉載于:https://www.cnblogs.com/L1nke/p/4947693.html
總結
以上是生活随笔為你收集整理的第九周(11.02-11.08)学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Codeforces Good Bye
- 下一篇: mac及idea常用快捷键