檔案IO不帶緩衝,每個read和write都調用核心中的相應系統調用。
檔案IO常用函數:
open,close,read,write,lseek
對於核心而言,所有開啟檔案都有檔案描述符引用。
檔案描述符是一個非負整數。當開啟一個現存檔案或建立一個新檔案時,你誒和向進程返回一個檔案描述符。
當讀、寫一個檔案時,用open返回的檔案描述符標識該檔案,將其作為參數傳給read或write。
1.open(被開啟的檔案名稱(可包含檔案路徑),int flag, mode)
falg : O_RDONLY,O_WDONLY,O_RDWR,O_CREAT,O_EXCL(如果存在返回錯誤資訊)
O_TRUNC(如果已存在,則刪除檔案中資料)
2.read(fd,buf,size_t count)
調用成功返回讀取的位元組數。
如果返回0,表示到達檔案的末尾。
如果返回-1,表示出錯,通過errno設定錯誤碼。
3.write()
4.lseek(fd,offset,whence)
5.開啟檔案目錄opendir()
6.擷取檔案屬性函數:這組函數還蠻重要的。
stat()擷取一個於此命名檔案有關的資訊結構
fstat()獲得已在描述符filedes上開啟的檔案的有關資訊
lstat()返回該符號連結的有關資訊,而不是有該符號連結引用的檔案資訊
stat內結構體中參數:st_mode ,st_mode 是被開啟檔案的屬性描述。
S_IFMT : 0x070000
switch(st.st_mode & S_IFMT) //判斷是何種類型的檔案
{
case S_IFREG: printf("-"); break;
case S_IFDIR: printf("d"); break;
case S_IFLNK: printf("l"); break;
case S_IFBLK: printf("b"); break;
case S_IFCHR: printf("c"); break;
case S_IFIFO: printf("p"); break;
case S_IFSOCK: printf("s"); break;
}
S_...是內部定義的一些宏,具體man一下看看
7.getopt函數查一下自己理解,getopt的作用是識別以“-”開頭的字元。
while ((ch = getopt(argc, argv, "la")) != EOF)
{
switch ( ch )
{
case 'a' :
printf("option a is set\n");
aflag = 1;
break;
case 'l' :
printf("option l is set\n");
lflag = 1;
break;
default :
printf("wrong option %c is set\n", optopt);
}
}
以及getpwuid(st.st_uid);getgrgid(st.st_gid);函數,分別是獲得目前使用者名,使用者組名
8.strtok()函數,是截斷字串的操作。以下的例子是利用空格來截斷。
這個函數比較怪異,第一次賦值的時候必須是buf,而以後的第一個參數是NULL,這個比較噁心....
arg[i++] = strtok(buf, " ");
do
{
arg[i++] = strtok(NULL, " ");
}while(arg[i-1] != NULL);
9.關於檔案夾操作的函數: DIR *opendir();struct dirent * readdir():內部有指標,可以自動移動檔案夾中下一個檔案,直到為空白)
例子:利用他們來完成檔案的拷貝#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>int main(int argc, char **argv){ int fd1, fd2; char buf[1024]; int nbyte; if(argc != 3) { printf("Using : %s srcfilename decfilename\n", argv[0]); return -1; } if((fd1 = open(argv[1], O_RDONLY)) < 0) { perror("open"); return -1; } if((fd2 = open(argv[2], O_WRONLY| O_CREAT | O_TRUNC, 0666)) < 0) { perror("open"); return -1; } while((nbyte = read(fd1, buf, sizeof(buf))) > 0) { write(fd2, buf, nbyte); } close(fd1); close(fd2); return 0;}開啟檔案目錄opendir()#include <stdio.h>#include <sys/types.h>#include <dirent.h>int main(int argc, char **argv){ DIR *dir; struct dirent *dirent; dir = opendir(argv[1]); while((dirent = readdir(dir)) != NULL) { printf("%s\n", dirent->d_name); }}擷取檔案屬性函數:stat()擷取一個於此命名檔案有關的資訊結構fstat()獲得已在描述符filedes上開啟的檔案的有關資訊lstat()返回該符號連結的有關資訊,而不是有該符號連結引用的檔案資訊利用stat實現ls的準系統:#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <stdio.h>#include <grp.h>#include <pwd.h>#include <time.h>int main(int argc, char **argv){ struct stat st; int i; struct passwd *pw; struct group *gr; struct tm *tm; stat(argv[1], &st); switch(st.st_mode & S_IFMT) //判斷是何種類型的檔案 { case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFLNK: printf("l"); break; case S_IFBLK: printf("b"); break; case S_IFCHR: printf("c"); break; case S_IFIFO: printf("p"); break; case S_IFSOCK: printf("s"); break; } for(i = 8; i >= 0; i--) { if(st.st_mode & (1 << i)) //st.st_mode後8位,判斷檔案許可權 { switch(i%3) { case 2: printf("r"); break; case 1: printf("w"); break; case 0: printf("x"); break; } } else printf("-"); } pw = getpwuid(st.st_uid); gr = getgrgid(st.st_gid); printf("%2d %s %s %4ld", st.st_nlink, pw->pw_name, gr->gr_name, st.st_size); tm = localtime(&st.st_ctime); printf(" %04d-%02d-%02d %02d:%02d",tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); printf(" %s\n", argv[1]); return 0;}