第九周(11.02-11.08):
估算學習時間:共8小時
讀書:4
代碼:1
做業:1
博客:2
實際學習時間:共12小時
讀書:4
代碼:2
做業:2
博客:4node
教材第八章《異常控制流》程序員
全部的I/O設備,如網絡、磁盤和終端,都被模型化爲文件,而全部的輸入和輸出都被當作對相應的文件的讀和寫來執行。這種將設備優雅地映射爲文件的方式,容許Unix內核引出一個簡單、低級的的應用接口,稱爲Unⅸ I/O,這使得全部的輸入和輸出都能以一種統一且一致的方式來執行:編程
進程是經過調用open函數來打開一個已存在的文件或者建立一個新文件緩存
O_RDONLY
O_WRONLY
O_RDWR安全
O_CREAT
O_TRUNC:若是文件已經存在,就截斷它。
O_APPEND網絡
應用程序是經過分別調用系統函數 read和write函數來執行輸入和輸出的。數據結構
在某些狀況下,read和write傳送的字節比應用程序要求的要少。出現這種狀況的可能的緣由有:less
讀時遇到EOF。假設該文件從當前文件位置開始只含有20個字節,而應用程序要求咱們以50個字節的片進行讀取,這樣一來,這個read的返回的值是20,在此以後的read則返回0。socket
- 從終端讀文本行。若是打開的文件是與終端相關聯的,那麼每一個read函數將一次傳送一個文本行,返回的不足值等於文本行的大小。
讀和寫socket。若是打開的文件對應於網絡套接字,那麼內部緩衝約束和較長的網絡延遲會致使read和write返回不足值。函數
RIO提供了兩類不一樣的函數:
rio_readn函數從描述符fd的當前文件位置最多傳送n個字節到存儲器位置usrbuf。相似的rio_writen函數從位置usrbuf傳送n個字節到描述符fd。rio_readn函數在遇到EOF時只能返回一個不足值。rio_writen函數毫不會返回不足值。
注意:若是rio_readn和rio_writen函數被一個從應用信號處理程序的返回中斷,那麼每一個函數都會手動地重啓read或write。
一個文本行就是一個由 換行符 結尾的ASCII碼字符序列。在Unix系統中,換行符是‘\n’,與ASCII碼換行符LF相同,數值爲0x0a。假設咱們要編寫一個程序來計算文本文件中文本行的數量應該如何來實現呢?
一種方法是用read函數來一次一個字節地從文件傳送到用戶存儲器,檢查每一個字節來查找換行符。這種方法的問題就是效率不高,每次取文件中的一個字節都要求陷入內核。
一種更好的方法是調用一個包裝函數(rio_readlineb),它從一個內部緩衝區拷貝一個文本行,當緩衝區變空時,會自動的調用read系統調用來從新填滿緩衝區。
應用程序可以經過調用stat和fstat函數,檢索到關於文件的信息。
stat函數結構
st_size成員包含了文件的字節數大小。st_mode成員則編碼了文件訪問許可位和文件類型。Unix識別大量不一樣的文件類型。普通文件包括某種類型的二進制或文本數據。對於內核而言,文本文件和二進制文件毫無區別。
目錄文件包含關於其餘文件的信息。套接字是一種用來經過網絡與其餘進程通訊的文件。Unix提供的宏指令根據st_mode成員來肯定文件的類型。
內核用三個相關數據結構來表示打開的文件
描述符表
文件表
v-node表
Unix外殼提供了I/O重定向操做符,容許用戶將磁盤文件和標準輸入輸出聯繫起來。
ANSI C定義了一組高級輸入輸出函數,成爲標準I/O庫,爲程序員提供了Unix I/O的較高級別的替代。這個庫(libc)提供了打開和關閉文件的函數(fopen和fclose)、讀和寫字節的函數(fread和fwrite)、讀和寫字符串的函數(fgets和fputs)、以及複雜的格式化I/O函數(printf和scanf)。
標準I/O庫將一個打開的文件模型化爲一個流。對於程序員而言,一個流就是一個指向FILE類型的結構的指針。每一個ANSI C程序開始時都有三個打開的流stdin、stdout和stderr,分別對應於標準輸入、標準輸出和標準錯誤:
#include<stdio.h> extern FILE *stdin; extern FILE *stdout; extern FILE *stderr;
這一章討論過的各類I/O包
標準I/O流,從某種意義上來講是全雙工的,由於程序可以在同一個流上執行輸入和輸出。
建議在網絡套接字上不要使用標準I/O函數來進行輸入和輸出。而要使用健壯的RIO函數。
怎樣學習系統編程(利用Linux學習Linux編程)
1 分析實用程序
/bin, /usr/bin, /usr/local/bin
學習使用工具,分析工具,瞭解功能和原理
2 學習系統調用
函數和系統調用本質上都是函數。不一樣的庫,不一樣的頭文件
分析須要哪些系統調用,學習系統調用的使用方法:參數?返回值?
3 編程實現
利用上面的原理和一組協同工做的系統調用,本身編程實現使用程序的功能
或積極主動抄代碼,學習那些系統調用是協同工做的
C語言的學習能夠參考這個思路,實現標準庫
伴隨咱們學習常常要問的三個問題:
能作什麼?
如何實現?
本身如何編寫?
好比說Linux操做系統
能作什麼?
登陸-運行程序-註銷
如何登陸?如何獲取程序名?如何運行程序?
目錄操做:目錄樹:ls,cd,pwd,mkdir,rmdir
目錄樹如何組織的?目錄存在哪?什麼是當前目錄?
文件操做:cat, more/less/pg, cp, mv, lpr
文件數據如何存儲?如何複製,移動,更名?文件名存在哪?
文件訪問控制:ugo
如何設置?
從OS的角度看: 網絡遊戲
通訊
協做
網絡訪問
bc/dc---->網絡 B/S
標準I/O 學習示例:more
能作什麼?用一下
使用方法
more filename
more < filename
command | more
如何實現?
僞代碼:
若是用戶沒有輸入文件名
輸出鍵盤輸入內容
對整個文件
顯示24行
提示用戶選擇 空格 回車 q
若是用戶選擇空格
顯示下24行
若是用戶選擇回車
顯示下一行
若是用戶選擇 q
退出
函數調用:
fopen/fclose
stdin stdout stderr
fgets/fputs
getchar/putchar
printf("\033[7m more? \033[m")
本身編寫:
如何判斷讀到文件尾部了?
feof
fgets的返回值是0
fseek 與文件讀寫位置
問題:
選擇都要回車
文字和反白more一塊兒上滾
百分比
適應窗口
重定向: who | more, ls |more
/dev/tty(流與文件)
系統調用:文件I/O 如何用Linux學習系統編程
多用戶系統如何知道誰在使用系統?who
who能作什麼?使用一下
man who (info who; who --help)
如何實現who?
閱讀ManPages
man man
搜索ManPages
man -k
man -k XXX | grep -i YYY
閱讀頭文件
參閱see also
man who
man -k utmp
man 5 utmp
utmp.h
grep -i XXX -nr /usr/include
UTMP_FILE
struct utmp
ut_line
僞代碼:
打開utmp文件
針對文件
讀取一條記錄
顯示記錄
關閉文件
哪些系統調用?
man -k file | grep -i read
see also
open/read/close
struct utmp s;
read( fd, &s, sizeof(s));
man
cf fopen fread fclose
本身編寫who:
read: return value
/var/run/utmp
var/run/unp
問題:空白記錄
ut_type
時間轉換
man -k time | grep -i transform (trans)
asctime(3)
ctime(3)
localtime(3)
man -k time | grep -i convert
無
查找關鍵字:至少漢語有想法
轉換
時間格式
man -k time | grep -i format
strftime(3)
如何複製文件?cp
cp能幹什麼?
cp src dst
如何實現cp?
open/close
open(fff, O_WRONLY|O_CREAT,0644)
creat(fff, 0644);
n = read(fd, buf, BUFSIZE);//#define BUFSIZE 4096
write(fd, buf, n);
僞代碼:
打開源文件
建立目標文件
針對源文件
把源文件讀入緩衝區
把緩衝區內容寫入目標文件
關閉源文件和目標文件
本身編寫cp:
系統調用錯誤處理:
錯誤種類:errno
顯示錯誤消息:perror(3)
錯誤處理封裝函數
fork()
if((pid = fork()) < 0)
unix_error("fork error");
return pid;
學有餘力者:
ac last cat head tail od dd
read/write能夠讀取文件內容,如何讀取文件名和文件屬性?ls
ls能幹什麼?
ls
ls -l
ls -a
ls -lu:最後訪問時間
ls -s:以塊爲單位的文件大小
ls -t:按時間排序
ls -F:顯示文件類型
列出文件目錄
顯示文件信息
如何列出文件目錄?
如何顯示文件屬性?
如何判斷一個名字是文件仍是目錄?
文件樹
文件和目錄被組織成目錄樹(tree),節點是目錄或者文件
目錄是一種特殊文件,文件內容就是目錄和文件的名字,與utmp相似
與文件不一樣,目錄不會爲空
如何實現ls?
man -k direct
man -k direct | grep -i read
man -k direct | grep -i entry
readdir
see also: opendir closedir
總結:代碼模式
fopen fread/fwrite fclose
open read/write close
opendir readdir closedir
僞代碼:
打開目錄文件
針對目錄文件
讀取目錄條目
顯示文件名
關閉文件目錄文件
本身編寫ls:
傳入參數,顯示任意目錄: ls /tmp; ls /; ls /dev
分欄
.開頭隱含文件:-a
排序:man -k sort
代碼庫:DRY
xxx_uitl.h xxx_util.c
出錯處理,參數處理,經常使用結構...
xxx_datastru.h xxx_datastru.c
鏈表,雙向鏈表
樹,圖。。。
xxx_algorith.h xxx_algorthm.c
ls -l能作什麼?
顯示文件信息:模式(文件類型file(1),訪問控制),連接數,文件全部者,組,大小,最後修改時間,文件名
如何實現ls -l?
man -k file | grep -i infomation (status, property, attribute)
stat(1) stat(2)
struct stat
最後修改時間:st_mtime ctime
模式:st_mode
type ugs rwx rwx rwx
八進制掩碼
struct stat info;
if ((info.st_mode & 0170000) == 0040000)
printf("這是一個目錄\n");
文件類型宏
struct stat info;
if (S_ISDIR(info.st_mode))
printf("這是一個目錄\n");
訪問控制屬性?好比說本人能不能寫?如何定義宏?
S_ISREG(mod) '-'
S_ISDIR(mode) 'd'
S_ISCHR(mode) 'c'
S_ISBLK(mode)) 'b'
UID/GID
/etc/passwd
getpwuid(3)
struct passwd
/etc/group
getgrgid(3)
struct group
本身編寫ls -l: ls2.c
stat(2) struct stat
getpwuid(3) struct passwd
getgrgid(3) struct group
記錄計數
按文件名排序 qsort
文件屬性修改與open/creat
open/creat umask(1) umask(2)
chmod(1) chmod(2)
chown(1) chgrp(1) chown(2)
touch(1) utime(2)
mv(1) rename(2)
學有餘力:tree chmod file chown chgrp finger touch
tree ls-R
文件包含數據,目錄是文件列表,目錄構成目錄樹。
文件在目錄中什麼意思?
用戶的主目錄(home)是什麼意思?
文件系統(解決的問題參考教材)
路徑:絕對路徑,相對路徑。pwd
用戶眼中的文件系統
目錄和文件:構成目錄樹
目錄命令:
. .. /
mkdir
rmdir
-p
mv
cd
pwd
...
練習:構建一棵目錄樹
文件命令:
cp
-r
cat
mv
rm
-r
ln
ls
...
目錄樹命令
tree
ls -R
chmod -R
du
find:注意與grep的區別
...
目錄樹的深度??
思考: 文件系統造成目錄樹,操做系統提供相應的操做命令來協同工做 目錄是什麼? 如何知道文件所處的目錄? 切換目錄(cd)是什麼意思? pwd如何自知道你處的目錄?