1、linux系統調用及用戶編程接口(API)
系統調用:所謂系統調用是指操作系統提供給用戶的一組“特殊”接口,用戶程序可以通過這組“特殊”接口來獲得操作系統內核提供的的服務;
為什么用戶程序不能直接訪問系統內核提供的服務呢?
由于在Linux中,為了更好地保護內核空間,將程序的運行空間分為內核空間和用戶空間(也就是常稱的內核態和用戶態),它們分別運行在不同的級別上,在邏輯上是相互隔離的。因此,用戶進程在通常情況下不允許訪問內核數據,也無法使用內核函數,它們只能在用戶空間操作用戶數據,調用用戶空間的函數。
用戶編程接口(API)
系統調用并不是直接與程序員進行交互的,它僅僅是一個通過軟中斷機制向內核提交請求,以獲取內核服務的接口。在實際使用中程序員調用的通常是用戶編程接口—API;
系統命令相對API更高了一層,它實際上一個可執行程序,它的內部引用了用戶編程接口(API)來實現相應的功能;
2、Linux中文件及文件描述符概述
Linux文件:Linux一點哲學,“一切皆為文件”;在Linux中對目錄和設備的操作都等同于對文件的操作;Linux文件可分為:普通文件,目錄文件,鏈接文件,設備文件;
文件描述符是一個非負的整數,它是一個索引值,并指向內核中每個進程的記錄表中;
一個進程啟動時,都會打開三個文件:
標準輸入: STDIN_FILENO 0
標準輸出: STDOUT_FILENO 1
標準出錯處理: STDERR_FILENO 2
例:
#include <unistd.h>
Int main()
{
char str[5];
read (STDIN_FILENO,str,5);
write(STDOUT_FILENO,str,5);
return 0;
}
3、不帶緩存的(系統調用)-文件訪問
①創建
int creat(const char *filename, mode_t mode )
filename :創建的文件名(包含路徑,缺省為當前路徑)
mode:創建模式
常創建模式:
S_IRUSR 可讀
S_IWUSR 可寫
S_IXUSR 可執行
S_IXRWU 可讀、可寫、可執行
除用以上宏來選擇創建模式,也可以用數字來表示
②打開
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags,mode_t mode);
返回值:成功返回新分配的文件描述符,出錯返回-1并設置errno
pathname是要打開或創建的文件的名字
flags參數可用來說明此函數的多個選擇項
mode對于open函數而言,僅當創建新文件時才使用第三個參數
Flag參數:以下可選項可以同時指定0個或多個,和必選項按位或起來作為flags參數。
O_CREAT若此文件不存在則創建它。使用此選擇項時,需同時說明第三個參數mode,用其說明該新文件的存取權限。
O_NONBLOCK如果p a t h n a m e指的是一個塊特殊文件或一個字符特殊文件,則此選擇項為此文件的本次打開操作和后續的I / O操作設置非阻塞方式。
O_TRUNC:把打開的文件的長度減短為零(清空打開的文件)。
O_EXCL:糾錯。
Mode參數:以下三個常數中必須指定一個,且僅允許指定一個(這些常數定義在<fcntl.h>頭文件中)
O_RDONLY 只讀打開
O_WRONLY 只寫打開
O_RDWR 讀、寫打開
O_APPEND 追加,自動定位到末尾
O_WRONLY|O_CREAT|O_TRUNL相當于creat
③關閉
int close(int fd)
fd:文件描述符;
④讀
int read(int fd, const void *buf, size_t length)
功能:從文件描述符fd所指定的文件中讀取length個字節到buf所指向的緩沖區中,返回值為實際讀取的字節數。
⑤寫
int write(int fd, const void * buf, size_t length)
功能:把length個字節從buf指向的緩沖區中寫到文件描述符fd所指向的文件中,返回值為實際寫入的字節數。
⑥定位
int lseek(int fd, offset_t offset, int whence)
功能:將文件讀寫指針相對whence移動offset個字節。操作成功時,返回文件指針相對于文件頭的位置。
whence可使用下述值:
SEEK_SET:相對文件開頭
SEEK_CUR:相對文件讀寫指針的當前位置
SEEK_END:相對文件末尾
offset可取負值,表示向前移動。例如下述調用
可將文件指針相對當前位置向前移動5個字節:
lseek(fd, -5, SEEK_CUR)
如何利用lseek來計算文件長度?
由于lseek函數的返回值為文件指針相對于文件頭的位置,因此下面調用的返回值就是文件的長度:lseek(fd, 0, SEEK_END)
4、帶緩存的(庫函數)-文件訪問
C庫函數的文件操作是獨立于具體的操作系統平臺的,不管是在DOS、Windows、Linux還是在VxWorks中都是這些函數。
①、創建和打開
FILE *fopen(const char *filename, const char *mode)
filename:打開的文件名(包含路徑,缺省為當前路徑)
mode:打開模式
“r”:只讀,文件必須已存在
“w”:只寫,如果文件不存在則創建,如果文件已存在則把文件長度截斷(Truncate)為0字節再重新寫,也就是替換掉原來的文件內容
“a”:只能在文件末尾追加數據,如果文件不存在則創建
“r+”:允許讀和寫,文件必須已存在
“w+”:允講讀和寫,如果文件不存在則創建,如果文件已存在則把文件長度截斷為0字節再重新寫
“a+”:允許讀和追加數據,如果文件不存在則創建
②讀
size_t fread(void *ptr, size_t size, size_t n, FILE* stream)
功能:從stream指向的文件中讀取n個字段,每字段為size字節,并將讀取的數據放入ptr所指的字符數組中,返回實際已讀取的字段數。
③寫
size_t fwrite (const void *ptr, size_t size, size_t n,FILE *stream)
功能:從緩沖區ptr所指的數組中把n個字段寫到stream指向的文件中,每個字段長為size個字節,返回實際寫入的字段數
④讀字符
int fgetc(FILE *stream)
從指定的文件中讀一個字符
例:
#include<stdio.h>
main()
{
FILE *fp;
char ch;
if((fp=fopen("c1.txt","rt"))==NULL)
{
PRintf("/nCannot open file strike any key exit!");
getchar();
exit(1);
}
ch=fgetc(fp);
while(ch!=EOF)
{
putchar(ch);
ch=fgetc(fp);
}
fclose(fp);
}
⑤寫字符
int fputc(int c, FILE *stream)
向指定的文件中寫入一個字符
#include<stdio.h>
main()
{
FILE *fp;
char ch;
if((fp=fopen("string","wt+"))==NULL)
{
printf("Cannot open file,strike any key exit!");
getch();
exit(1);
}
printf("input a string:/n");
ch=getchar();
while (ch!='/n')
{
fputc(ch,fp);
ch=getchar();
}
printf("/n");
fclose(fp);
}
補充:
#include<stdio.h>
FILE * fopen (int fd, const char * mode)
將打開的文件描述符打開成FILE形文件指針
字符串:按行讀?。篶har * fgets(char * str,int size,FILE * stream)
寫入字符串:int fputs(const char * str, FILE * stream);
新聞熱點
疑難解答