
1.打开目录(1)opendir头文件 #includedirent.h #includesys/types.hDIR *opendir(const char *name);功能打开一个目录并返回一个关联的目录流参数name 要打开的目录名返回值 成功 返回目录流指针DIR*失败 返回如何打开一个目录#includestdio.h #includedirent.h #includesys/types.h int main(int argc, const char *argv[]) { DIR *dp opendir(.); if(dp NULL) { perror(open fail); return -1; } return 0; }2.读(1)readdirstruct dirent *readdir(DIR *dirp)struct dirent {ino_t d_ino; /* Inode number */off_t d_off; /* Not an offset; see below */unsigned short d_reclen; /* Length of this record */unsigned char d_type; /* Type of file; not supportedby all filesystem types */char d_name[256]; /* Null-terminated filename */};d_typeDT_BLK This is a block device.DT_CHR This is a character device.DT_DIR This is a directory.DT_FIFO This is a named pipe (FIFO).DT_LNK This is a symbolic link.DT_REG This is a regular file.DT_SOCK This is a UNIX domain socket.DT_UNKNOWN The file type could not be determined.功能读一个目录参数dirp 目录流指针返回值成功时 返回一个目录结构体指针 struct dirent*失败时返回NULL到达目录结尾返回MULL练习实现 ls 功能#includestdio.h #includedirent.h #includesys/types.h int main(int argc, const char *argv[]) { if(argc ! 2) { return -1; } DIR *dp opendir(argv[1]); if(dp NULL) { perror(open fail); return -1; } struct dirent *a NULL; while(1) { a readdir(dp); if(a NULL) { break; } if(a-d_name[0] ! .) printf(%s ,a-d_name); } putchar(\n); return 0; }运行结果3.关闭(1)closedirint closedir(DIR *dirp)功能关闭目录流参数dirp 要关闭的目录流指针返回值 成功 0失败 -1 error会被设置注意不要多次释放结果练习实现一个功能统计某个目录下 常规文件 和 目录文件的个数#includestdio.h #includedirent.h #includesys/types.h int main(int argc, const char *argv[]) { if(argc ! 2) { return -1; } DIR *dp opendir(argv[1]); if(dp NULL) { perror(open fail); return -1; } struct dirent *a NULL; int len 0; int cnt 0; while(1) { a readdir(dp); if(a NULL) { break; } if(a-d_type DT_DIR) len; if(a-d_type DT_REG) cnt; } printf(%d %d\n,len,cnt); closedir(dp); return 0; }运行结果4.更改目录1chdirint chdir(const char *path);功能更改调用进程当前程序的当前工作目录参数path 当前的工作路径5.获取当前目录1getcwdchar *getcwd(char *buf,size_t size)功能获得当前的工作路径参数buf 保存工作路径空间的首地址size 保存路径空间的长度使用#includestdio.h #includeunistd.h int main(int argc, const char *argv[]) { char buf[1024] {0}; getcwd(buf,sizeof(buf)); //当前目录 printf(buf %s\n,buf); chdir(/home/linux); //根目录 getcwd(buf,sizeof(buf)); printf(buf %s\n,buf); return 0; }运行结果6.创建目录1mkdirint mkdir(const char *pathname, mode_t mode) 0666 0777功能创建一个目录参数pathname路径名称mode mode umask返回值 成功返回0 失败返回-1#includestdio.h int main(int argc,const char *argv[]) { mkdir(argv[1],0666); return 0; }7.删除目录1rmdir功能删除目录要求目录本身是空的#includestdio.h #includeunistd.h int main(int argc,const char *argv[]) { if(rmdir(argv[1])0) { perror(rmdir fail); return -1; } return 0; }练习打印当前自己所在路径切换到主目录下创建一个dir123目录到这个目录下创建一个123.txt的文件#includestdio.h #includeunistd.h #includedirent.h #includesys/types.h #includefcntl.h #includesys/stat.h int main(int argc,const char *argv[]) { char buf[1024] {0}; getcwd(buf,sizeof(buf)); printf(before cd %s\n,buf); chdir(/home/linux); getcwd(buf,sizeof(buf)); printf(after cd %s\n,buf); mkdir(dir123,0777); chdir(dir123); open(123.txt,O_WRONLY|O_CREAT,0666); return 0; }8.获取文件属性1statint stat(const char *pathname, struct stat *statbuf)功能获取文件的属性参数pathnamestatbuf返回值 成功返回0失败返回-1mode_t st_mode 权限信息如何获取文件类型信息呢跟掩码做 运算将算出的结果与掩码下面的文件类型做对比值相同就为相应的文件类型S_IFMT 0170000 ---------二进制 1111| 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 * * * R | W X R W X R W X1 1 1 1 --user----- ---group-- --others--switch(st.st_mode S_IFMT) //与掩码做与运算看值与哪种文件类型匹配求出文件类型 { case S_IFSOCK: printf(s); break; case S_IFLNK: printf(l); break; case S_IFREG: printf(-); break; case S_IFBLK: printf(b); break; case S_IFDIR: printf(d); break; case S_IFCHR: printf(c); break; case S_IFIFO: printf(p); break; }如何获取权限信息呢与上面判断文件类型类似st.st_mode S_IRUSR?putchar(r):putchar(-); st.st_mode S_IWUSR?putchar(w):putchar(-); st.st_mode S_IXUSR?putchar(x):putchar(-); st.st_mode S_IRGRP?putchar(r):putchar(-); st.st_mode S_IWGRP?putchar(w):putchar(-); st.st_mode S_IXGRP?putchar(x):putchar(-); st.st_mode S_IROTH?putchar(r):putchar(-); st.st_mode S_IWOTH?putchar(w):putchar(-); st.st_mode S_IXOTH?putchar(x):putchar(-);----------------------------------------------------------------------------------------------------------------------------nlink_t st_nlink硬链接硬链接本质是给我们的文件取别名。与源文件直接关联。修改一个另一个同时被修改。删除一个另一个不会有影响。命令ln源文件名硬链接文件名软链接本质类似于我们windows的快捷方式用来记录我们目标的路径命令ln -s 源文件 软链接文件---------------------------------------------------------------------------------------------------------------------------图中第一个linux是用户名第二个linux是所在组组名uid_t st_uid 用户IDgid_t st_gid 组所在ID如何将数值转化成名字printf( %-10s ,getpwuid(st.st_uid)-pw_name); printf( %-10s ,getgrgid(st.st_gid)-gr_name);-------------------------------------------------------------------------------------------------------------------------off_t st_size 文件大小printf( %-10ld ,st.st_size);----------------------------------------------------------------------------------------------------------------------time_t st_atime 最后访问的时间time_t st_mtime 最后修改的时间time_t st_ctime 最后的状态改变的时间//6.最后被修改时间 struct tm * ptm localtime(st.st_mtime); printf(%02d月 %02d %02d:%02d ,ptm-tm_mon1,ptm-tm_mday,ptm-tm_hour,ptm-tm_min);----------------------------------------------------------------------------------------------------------------------#includestdio.h #includeunistd.h #includedirent.h #includesys/types.h #includefcntl.h #includesys/stat.h int main(int argc, const char *argv[]) { if(argc ! 2) { return -1; } struct stat st; if(stat(argv[1],st) 0) { perror(stat fail); return -1; } printf(File: %s\n,argv[1]); printf(Size: %ld \tBlocks: %ld \t IO Block: %ld\n,st.st_size,st.st_blocks,st.st_blksize); return 0; }运行结果合起来就可以实现linux 命令中的 ls -l 功能#include stdio.h #include sys/types.h #include sys/stat.h #include unistd.h #include pwd.h #include grp.h #include time.h #include dirent.h int do_ls_file(const char *filename) { struct stat st; if (stat(filename,st) 0) { perror(stat fail); return -1; } //1.文件类型 switch(st.st_mode S_IFMT) { case S_IFSOCK: putchar(s); break; case S_IFLNK: putchar(l); break; case S_IFREG: putchar(-); break; case S_IFBLK: putchar(b); break; case S_IFDIR: putchar(d); break; case S_IFCHR: putchar(c); break; break; case S_IFIFO: putchar(p); break; } //2.权限 st.st_mode S_IRUSR ?putchar(r):putchar(-); st.st_mode S_IWUSR ?putchar(w):putchar(-); st.st_mode S_IXUSR ?putchar(x):putchar(-); st.st_mode S_IRGRP ?putchar(r):putchar(-); st.st_mode S_IWGRP ?putchar(w):putchar(-); st.st_mode S_IXGRP ?putchar(x):putchar(-); st.st_mode S_IROTH ?putchar(r):putchar(-); st.st_mode S_IWOTH ?putchar(w):putchar(-); st.st_mode S_IXOTH ?putchar(x):putchar(-); //3.硬连接数 printf( %-3ld ,st.st_nlink); //4.用户名和组名 printf( %-10s ,getpwuid(st.st_uid)-pw_name); printf( %-10s ,getgrgid(st.st_gid)-gr_name); //5.大小 printf( %-10ld ,st.st_size); //6.最后被修改时间 struct tm * ptm localtime(st.st_mtime); printf(%02d月 %02d %02d:%02d ,ptm-tm_mon1,ptm-tm_mday,ptm-tm_hour,ptm-tm_min); //7.文件名 printf( %s \n,filename); return 0; } int do_ls_dir(const char * dirname) { if (dirname NULL) { return -1; } if (chdir(dirname) 0) { perror(chdir fail); return -1; } DIR *dp opendir(dirname); if (dp NULL) { perror(opendir fail); return -1; } while (1) { struct dirent *pdir readdir(dp); if (pdir NULL) break; // printf(name %s\n,pdir-d_name); do_ls_file(pdir-d_name);// } closedir(dp); } int main(int argc, const char *argv[]) { //do_ls(argv[1]); //do_ls_dir(argv[1]); if (argc ! 2) { printf(Usage %s dir or filename\n,argv[0]); return -1; } struct stat st; if (stat(argv[1],st) 0) { perror(stat fail); return -1; } if (st.st_mode S_IFDIR) { do_ls_dir(argv[1]); }else { do_ls_file(argv[1]); } return 0; }