應用程式
——————————
核心 驅動
作業系統 系統移植
--------------------
硬體api庫
應用程式------>核心
系統程式設計 i/o 程序 網路 直接
api 間接(減少了系統呼叫效率更高)
i/o分為 檔案i/o----->核心標準i/o--------->核心
ps -axj 檢視系統程序資訊
#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
//close() read() write() lseek()
#include "sys/types.h"//常用的巨集
#include "fcntl.h"
//open()
#include"string.h"
int main()
printf("open file sucess\n");
ret=write(fd,str,sizeof(str)); //返回真實寫入的字元長度
lseek(fd,0,seek_set);
//修改當前檔案位移量
printf("write %d byte in file abc\n",ret);
ret=read(fd,readstr,5); //返回讀取到的字元長度
printf("read %d byte in file abc is %s\n",ret,readstr);
close(fd);
return 0;}
原型 int open(const char *pathname, int flags, mode_t mode);
引數 pathname 被開啟的檔名(可包括路徑名)。
o_rdonly:唯讀方式開啟檔案。
o_wronly:可寫方式開啟檔案。(這三個引數互斥)
o_rdwr:讀寫方式開啟檔案。
o_creat:如果該檔案不存在,就建立乙個新的檔案,並用第三的引數為其設定許可權。
原型 off_t lseek(int fd,off_t offset,int whence);
引數 fd:檔案描述符。
offset:偏移量,每一讀寫操作所需要移動的距離,單位是位元組的數量,可正可負(向前移,向後移)
whence
(當前位置基點): seek_set:當前位置為檔案的開頭,新位置為偏移量的大小。
seek_cur:當前位置為檔案指標的位置,新位置為當前位置加上偏移量。
seek_end:當前位置為檔案的結尾,新位置為檔案的大小加上偏移量的大小
返回值 成功:檔案的當前位移
-1:出錯
通過乙個簡單的copy程式,完成檔案的複製程式,了解基本的檔案i/o檔案讀寫的基本步驟
編寫**,實現相應的功能
開啟原始檔
開啟目標檔案
迴圈讀取原始檔並寫入目標檔案
關閉原始檔
關閉目標檔案
#include
#include"unistd.h"
#include"stdlib.h"
#include"sys/types.h"
#include"fcntl.h"
#define max 256
int main(int argc,char *argv)
fd1 = open(argv[1],o_rdonly);
if(fd1 == -1)
if(fd2==-1)
if(fd2 == -1)
dowhile(i==256);
return 0;
}
標準i/o有三種快取1全快取 2行快取 3無快取
inode---結構體---------指標---------
ext3 / \
|| 磁碟塊(檔案內容,軟鏈結指標) <||
| inode-------------------
目錄 |
|磁碟塊(檔名鍊錶形式)<----
軟鏈結 ln -s xx cc
「快捷方式」
硬鏈結 ln xx cc
「對檔案xx的備份」
乙個小例子
#include
int main()
1 _exit(0); 2 fflush(stdout);_exit(0); 3 exit(0);
umask 取反後與設定的許可權相與
開啟函式檔案描述符open(檔案位置,開啟方式,許可權)
檔案流指標fopen(檔案位置,開啟方式)
r唯讀檔案存在 +讀寫 w寫,沒有檔案建立,清零 a寫沒有檔案建立,追加
fgetc(fp)
fgets(buf,100,fp) fread(指標,size,num,fp)
fputc(int c,fp)
fputs(buf,fp)
fwrite(同上)
用以上3對函式編寫複製函式
#include
#include"stdlib.h"
int main(int argc,char *argv)
fd1 = fopen(argv[1],"r");
if(fd1 == null)
fd2 = fopen(argv[2],"w");
if(fd2==null)
while((i=fgetc(fd1))!=eof)
return 0; }
#include
#include"stdlib.h"
#include"string.h"
#define n 100
int main(int argc,char *argv)
fd1 = fopen(argv[1],"r");
if(fd1 == null)
fd2 = fopen(argv[2],"w");
if(fd2==null)
while(fgets(str,n,fd1)!=null)
else
if(str[n-2]=='\n')
i++;
fputs(str,fd2); }
printf("%d\n",i);
return 0; }
#include
#include"stdlib.h"
#define n 100
int main(int argc,char *argv)
fd1 = fopen(argv[1],"r");
if(fd1 == null)
fd2 = fopen(argv[2],"w");
if(fd2==null)
dowhile(i==n);
return 0; }
原帖位址
1.以非阻塞方式開啟檔案
呼叫open時,使用o_nonblock選項即可。
例項:#include
#include
#include
#include
#include
#define max 100000
#define len 1024
int main(int argc, char *argv[ ])
fd1 = open(argv[1], o_rdonly);
if(fd1 == -1)
fp = fopen(argv[2], "w");
if(fp == null)
fd2 = open("test.txt", o_wronly);
if(fd2 == -1)
rest = read(fd1, buf, max);
printf("get %d bytes from %s/n", rest, argv[1]);
while(rest > 0)
}printf("done/n");
return 0;}
觀察輸出系統中呼叫出錯原因的檔案,可以看到很多錯誤號為eagain的出錯提示資訊。
2.將乙個開啟的檔案設定為非阻塞方式
用fcntl,先用f_getfl得到狀態標誌字,之後用f_setfl設定相應的位。
//noblock_fcntl.c
#include
#include
#include
#include
#include
#define max 100000
#define len 1024
int main(int argc, char *argv[ ])
fd1 = open(argv[1], o_rdonly);
if(fd1 == -1)
fd2 = open(argv[2], o_wronly);
if(fd2 == -1)
fp = fdopen(fd2, "w");
if(fp == null)
flags = fcntl(stdout_fileno, f_getfl, 0);
if(flags == -1)
flags |= o_nonblock;
if(fcntl(stdout_fileno, f_setfl, flags) == -1)
rest = read(fd1, buf, max);
printf("get %d bytes from %s/n", rest, argv[1]);
while(rest > 0)
}printf("done/n");
close(fd1);
fclose(fp);
return 0;}
阻塞IO與非阻塞IO
阻塞io,當前程序因不滿足一些條件,而被掛起,即阻塞,cpu改去服務其它程序,read乙個普通檔案,就馬上執行,read乙個滑鼠,可是滑鼠沒有動,於是就阻塞了,阻塞的好處,利於os效能的發揮,cpu發揮高,雖然個體的費了點時間,但是總的效率得到了提高,阻塞在多路io的時候,缺陷就出來了,比如2路io...
非阻塞IO與阻塞IO
非阻塞式呼叫的問題 kibuv提供了乙個執行緒池 阻塞於非阻塞對於被呼叫者,即系統層面,系統為程式提供了阻塞呼叫和非阻塞呼叫,同步和非同步是對於呼叫者,就是自己的程式,發七呼叫,沒有其他操作,只是等待結果這個過程就是同步,發起呼叫後會等待結果,繼續完成其他的工作,等有回掉再執行,這個過程就是非同步的...
阻塞I O,非阻塞I O
拿 socket舉例。當read資料時,如果這時沒有資料可讀,阻塞i o會一直等待有資料讀,資料從kernel copy 到socket的buffer後返回 非阻塞i o會立即返回,但如果有資料可讀,非阻塞i o也是等資料從kernel copy 到socket的buffer後返回。以上是阻塞與非阻...