十三、linux编程中目录IO常用编程函数
概念:
????????索引節點,Inode是Index Node的縮寫,存儲于文件系統上的任何文件都可以用索引節點來表示,所以也可以說索引節點是整個linux文件系統的基礎。操作系統在讀取硬盤的時候不是一個塊一個塊的來讀取信息,因為這樣做的話效率太低,文件數據都儲存在“塊”中,那么很顯然,我們還必須找到一個地方儲存文件的元信息,比如文件的創建者、文件的創建日期、文件的大小等等。這種儲存文件元信息的區域就叫做inode,中文譯名為“索引節點”。
????????在Linux系統中,文件系統主要分為兩部分,一部分為元數據(metadata),另一部分為數據本身。元數據,換句話說,就是包含了數據有關信息的數據。索引節點就管理著文件系統中元數據的部分。
一、stat函數組(獲取文件信息,具體看stat結構體 )
1、頭文件、函數原型及相關結構體(可以通過man 2 stat 打開對應的stat幫助文檔)
/*所需頭文件*/ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> /*函數原型*/ int stat(const char *path, struct stat *buf); – 參數*path:文件路徑 – 參數*buf:文件信息 – 返回值:成功為0,否則為-1 int fstat(int fd, struct stat *buf); – 參數fd:文件描述符 – 參數*buf:文件信息 – 返回值:成功為0,否則為-1 int lstat(const char *path, struct stat *buf); – 參數*path:文件路徑 – 參數*buf:返回文件的信息,針對符號鏈接,lstat 返回鏈接本身,而不是而非目標文件 – 返回值:成功為0,否則為-1stat結構體包含對象:struct stat {dev_t st_dev; /* ID of device containing file */ino_t st_ino; /* inode number */mode_t st_mode; /* protection */nlink_t st_nlink; /* number of hard links */uid_t st_uid; /* user ID of owner */gid_t st_gid; /* group ID of owner */dev_t st_rdev; /* device ID (if special file) */off_t st_size; /* total size, in bytes */blksize_t st_blksize; /* blocksize for file system I/O */blkcnt_t st_blocks; /* number of 512B blocks allocated */time_t st_atime; /* time of last access */time_t st_mtime; /* time of last modification */time_t st_ctime; /* time of last status change */};2、具體使用方法及代碼:?
#include <stdio.h> //通過man文檔可以查看到stat函數組頭文件 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>//open函數的參數頭文件 #include <fcntl.h>int main(int argc,char *argv[]) {struct stat groupstat;int fd,ret;if(argc <2){printf("\nPlease input file path\n");return 1;}//stat函數測試 ret = stat(argv[1],&groupstat);if(ret){printf("Please make sure file path\n");return 1;}printf("stat function test , %s of st_ino inode is %ld\n",argv[1],groupstat.st_ino);//fstat函數測試fd = open(argv[1],O_RDWR|O_NOCTTY|O_NDELAY);if(fd<0){printf("Please make sure file path\n");return 1;}ret = fstat(fd,&groupstat);if(ret){printf("Please make sure file path\n");return 1;}printf("fstat function test , %s of st_ino inode is %ld\n",argv[1],groupstat.st_ino);//lstat函數測試 ret = lstat(argv[1],&groupstat);if(ret){printf("Please make sure file path\n");return 1;}printf("lstat function test , %s of st_ino inode is %ld\n",argv[1],groupstat.st_ino);return 0; }二、chmod函數組(設置文件權限 )
1、頭文件、函數原型及相關結構體(可以通過man 2 chmod打開對應的chmod幫助文檔)
/*頭文件*/ #include <sys/stat.h> /*函數原型*/ int chmod(const char *path, mode_t mode);// 修改指定路徑的文件權限 – 參數*path:文件路徑。 – 參數mode:直接使用數字即可。和前面命令中chmod 777 xxx 中的777 這個參數含義類似,也可以使用文檔中的組合值。 – 返回值:成功返回0,錯誤返回-1。 int fchmod(int fd, mode_t mode);// 修改打開的文件權限 – 參數fd:文件描述符。 – 參數mode:直接使用數字即可。和前面命令中chmod 777 xxx 中的777 這個參數含義類似,也可以使用文檔中的組合值。 – 返回值:成功返回0,錯誤返回-1。2、具體使用方法及代碼:?
#include <stdio.h>#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int main(int argc,char *argv[]) {int fd,ret;if(argc <3){printf("\nPlease input file path\n");return 1;}//chmod函數測試 ret = chmod(argv[1],0777);if(ret<0){printf("Please make sure file path\n");return 1;}printf("chmod %s 0777 is success!\n",argv[1]);//fchmod函數測試 fd = open(argv[2],O_RDWR|O_NOCTTY|O_NDELAY);if(fd<0){printf("Please make sure file path\n");return 1;}ret = fchmod(fd,0555);if(ret<0){printf("Please make sure file path\n");return 1;}printf("fchmod %s 0555 is success!\n",argv[1]);return 0; }三、獲取當前目錄
1、頭文件、函數原型及相關結構體(可以通過man 3 getcwd打開對應的getcwd幫助文檔)
/*頭文件*/ #include <unistd.h> /*函數原型*/ char *getcwd(char *buf, size_t size); – 參數*buf:保存當前目錄的緩沖區 – 參數size:在現代linux 中,buf 的長度至少可以為255 字節 – 返回值:成功返回指向當前目錄的指針,和buf 的值一樣,錯誤返回NULL char *getwd(char *buf); – 參數*buf:保存當前目錄的緩沖區 – 返回值:成功返回指向當前目錄的指針,和buf 的值一樣,錯誤返回NULL char *get_current_dir_name(void); – 參數:無 – 返回值:成功返回指向當前目錄的指針,錯誤返回NULL2、具體使用方法及代碼:?
#include <stdio.h> /*getcwd、getwd和get_current_dir_name 函數的頭文件*/ #define __USE_GNU #include <unistd.h>#define LENTH 255 int main() {char pwd[LENTH];char *wd; //getcwd函數測試 if(!getcwd(pwd,LENTH)){perror("getcwd");return 1;}printf("\ngetcwd pwd is %s\n",pwd);//getwd函數測試wd = getwd(pwd);if(!wd){perror("getcwd");return 1;}printf("\ngetwd pwd is %s\n",wd);//get_current_dir_name函數測試 wd = get_current_dir_name();if(!wd){perror("getcwd");return 1;}printf("\nget_current pwd is %s\n",wd);return 0; }四、創建目錄
1、頭文件、函數原型及相關結構體(可以通過man 2 mkdir打開對應的mkdir幫助文檔)
/*頭文件*/ #include <sys/stat.h> #include <sys/types.h> /*函數原型*/ int mkdir(const char *pathname, mode_t mode); – 參數:文件路徑 – 參數mode:直接使用數字即可。和前面命令中chmod 777 xxx 中的777 這個參數含義類似,也可以使用文檔中的組合值。 – 返回值:成功返回0,錯誤返回-1。2、具體使用方法及代碼:??
#include <stdio.h> //mkdir函數頭文件 #include <sys/stat.h> #include <sys/types.h>int main(int argc,char *argv[]) {int ret;//檢測參數 if(argc <2){printf("\nPlease input file path\n");return 1;} //使用mkdir函數新建目錄ret = mkdir(argv[1],0777);if(ret<0){printf("mkdir %s failed!\n",argv[1]);return 1;}printf("mkdir %s suceces!\n",argv[1]);return 0; }五、刪除目錄
1、頭文件、函數原型及相關結構體(可以通過man 2 rmdir打開對應的rmdir幫助文檔)
/*頭文件*/ #include <unistd.h> /*函數原型*/ int rmdir(const char *pathname); – 參數*pathname:文件和目錄的路徑 – 返回值:成功返回0,錯誤返回-12、具體使用方法及代碼:??
#include <stdio.h> //rmdir函數頭文件 #include <unistd.h>int main(int argc,char *argv[]) {int ret;//檢測參數 if(argc <2){printf("\nPlease input file path\n");return 1;} //使用rmdir函數刪除目錄ret = rmdir(argv[1]);//目錄要是絕對目錄if(ret<0){printf("rmdir %s failed!\n",argv[1]);return 1;}printf("rmdir %s suceces!\n",argv[1]);return 0; }六、改變當前工作目錄
1、頭文件、函數原型及相關結構體(可以通過man 2 chdir打開對應的chdir幫助文檔)
在實際應用中,代碼可能需要從當前目錄中進到其它目錄,這個時候首先需要使用 getcwd函數獲取當前目錄,保存起來,然后使用 chdir 跳到其它目錄,完成操作,然后再使用 chdir回到最初保存的目錄。
#include <unistd.h> /*函數原型*/ int chdir(const char *path);- 參數 *path:文件路徑- 返回值:成功返回 0,錯誤返回-1。 int fchdir(int fd);- 參數 fd:open 函數返回的句柄,文件描述符。- 返回值:成功返回 0,錯誤返回-1。2、具體使用方法及代碼:?
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //chdir和fchdir函數頭文件 #include <unistd.h>#define LENTH 255int main(int argc,char *argv[]) {int ret;char pwd[LENTH];//檢測參數 if(argc <3){printf("\nPlease input file path\n");return 1;}//getcwd函數獲取當前目錄 if(!getcwd(pwd,LENTH)){perror("getcwd");return 1;}printf("\ngetcwd pwd is %s\n",pwd);//使用chdir函數轉入其他目錄ret = chdir(argv[1]);if(ret){printf("Please make sure file path\n");return 1;}printf("chdir %s is success!\n",argv[1]);//轉入其他目錄,完成操作 //使用rmdir函數刪除目錄ret = rmdir(argv[2]);if(ret<0){printf("rmdir %s failed!\n",argv[2]);return 1;}printf("rmdir %s is success!\n",argv[2]);//再次使用chdir回到pwd保存的目錄ret = chdir(pwd);if(ret){printf("Please make sure file path\n");return 1;}printf("chdir %s is success!\n",pwd);return 0; }七、opendir和closedir目錄
1、頭文件、函數原型及相關結構體(可以通過man 3 opendir(closedir)打開對應的opendir(closedir)幫助文檔)
前面介紹open和close函數用于打開關閉文件,這里介紹的opendir和closedir用于打開目錄,相當于ls命令。
#include <sys/types.h> #include <dirent.h> /*函數原型*/ DIR *opendir(const char *name); – 參數:目錄的路徑。 – 返回值:成功返回指向目錄流的指針,錯誤返回NULL int closedir(DIR *dirp); – 參數:opendir 返回的dir 指針 – 返回值:成功返回0, 失敗返回-12、具體使用方法及代碼:?
#include <stdio.h> //opendir和closedir函數頭文件 #include <dirent.h> #include <sys/types.h>int main(int argc,char *argv[]) {int ret;DIR *dir;//檢測參數 if(argc <2){printf("\nPlease input file path\n");return 1;} //使用opendir函數打開目錄dir = opendir(argv[1]);if(dir==NULL){printf("opendir %s failed!\n",argv[1]);return 1;}printf("opendir %s suceces!\n",argv[1]); //使用closedir函數關閉目錄closedir(dir);return 0; }八、readdir讀取目錄信息
1、頭文件、函數原型及相關結構體(可以通過man 3 readdir打開對應的readdir幫助文檔)
在前面使用opendir打開目錄的基礎上,可以使用readdir讀取目錄信息。
#include <dirent.h> /*函數原型*/ struct dirent *readdir(DIR *dirp); – 參數dirp:opendir 函數打開目錄后返回的文件指針。 – 返回值:成功返回指向dirp 的指針dirent ,錯誤返回NULL。struct dirent {ino_t d_ino; /* inode number */off_t d_off; /* offset to the next dirent */unsigned short d_reclen; /* length of this record */unsigned char d_type; /* type of file; not supportedby all file system types */char d_name[256]; /* filename */};2、具體使用方法及代碼:??
#include <stdio.h> //opendir,closedir,readdir函數頭文件 #include <dirent.h> #include <sys/types.h>int main(int argc,char *argv[]) {int ret;DIR *dir;struct dirent *catlog; //檢測參數 if(argc <2){printf("\nPlease input file path\n");return 1;} //使用opendir函數打開目錄dir = opendir(argv[1]);if(dir==NULL){printf("opendir %s failed!\n",argv[1]);return 1;}printf("opendir %s suceces!\n",argv[1]); //使用readdir讀取目錄argv[1]catlog = readdir(dir);if(catlog == NULL){printf("readdir %s failed!\n",argv[1]);return 1;}printf("%s d_ino is %ld\n ",argv[1],catlog->d_ino); //使用closedir函數關閉目錄closedir(dir);return 0; }九、硬鏈接和軟鏈接(符號鏈接)
1、硬鏈接
????????在Linux系統中,多個文件名指向同一索引節點(Inode)是正常且允許的。一般這種鏈接就稱為硬鏈接。硬鏈接的作用之一是允許一個文件擁有多個有效路徑名,這樣用戶就可以建立硬鏈接到重要的文件,以防止“誤刪”源數據。(換句話說就是我們前面講得,文件的屬性和數據是分開的,將兩份不一樣的文件屬性同時指向同一份文件數據。那么這兩份文件屬性就是硬鏈接。)
硬鏈接函數
? int link(const char *oldpath, const char *newpath)
– 參數*oldpath:已有的文件路徑。
– 參數*newpath:新建的硬鏈接文件路徑。
– 返回值:成功返回0,錯誤返回-1。
2、軟鏈接
????????軟鏈接(也叫符號鏈接),類似于windows系統中的快捷方式,與硬鏈接不同,軟鏈接就是一個普通文件,只是數據塊內容有點特殊,文件用戶數據塊中存放的內容是另一文件的路徑名的指向,通過這個方式可以快速定位到軟連接所指向的源文件實體。軟鏈接可對文件或目錄創建。
軟鏈接函數
? int symlink(const char *oldpath, const char *newpath)
– 參數*oldpath:已有的文件路徑
– 參數*newpath:新建的符號鏈接文件路徑
– 返回值:成功返回0,錯誤返回-1
3、解除鏈接
解除鏈接函數
? int unlink(const char *pathname)
– 參數*pathname:鏈接文件的路徑
– 返回值:成功返回0,錯誤返回-1
– unlink指向軟鏈接,刪除軟鏈接;指向最后一個硬鏈接,相當于刪除文件。因為硬鏈接的文件數據至少要有一個硬鏈接,如果最后一個都被刪除,那么相當于文件數據也要刪除了。
十、文件拷貝
????????linux中,沒有專用的文件拷貝函數,而是通過從舊文件讀取(read函數),寫入(write函數)新文件,來實現文件的拷貝。
#include <stdio.h>#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h>//argv[1] is oldpath ; argv[2] is newpath #define LENTH 1024 int main(int argc,char *argv[]) {int fds,fdt;char buffer[LENTH];char *fileold,*filenew;fileold = argv[1];filenew = argv[2];if(argc <3){printf("\nPlease input file path\n");return 1;}//打開oldpath fds = open(fileold,O_RDWR);if(fds<0){printf("Please make sure file path\n");return 1;}//打開newpath,如果沒有則創建目標文件fdt = open(filenew,O_WRONLY|O_CREAT);if(fdt<0){printf("Please make sure file path\n");return 1;}//讀和寫操作while(read(fds,buffer,LENTH)){write(fdt,buffer,strlen(buffer));}//關閉文件close(fds);close(fdt);printf("cp to finished!\n");printf("cp %s to %s success!\n",fileold,filenew);return 0; }十一、文件移動
移動文件命令為mv,函數為rename。
文件移動函數:
int rename(const char *oldpath, const char *newpath)
– 參數*oldpath:舊的文件路徑
– 參數*newpath:新的文件路徑
– 返回值:成功返回0,錯誤返回-1
總結
以上是生活随笔為你收集整理的十三、linux编程中目录IO常用编程函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十二、Linux系统编程中man命令的使
- 下一篇: if/ else 你真的会吗?