1、stat、fstat、lstat函数
#include<sys/stat.h>
int stat(const char *pathname, struct stat *buf)
int fstat(int filedes, struct stat *buf)
int lstat(const char *pathname, struct stat *buf)
stat与lstat函数都需要给出文件的绝对路径,但是当文件是一个符号链接时,lstat会返回该链接的有关信息,而stat直接转到实际的文件位置,fstat需要给出文件描述符。三个函数都能得到文件的详细信息,信息保存在buf中。
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 */
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 */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
};
2、文件类型
unix下有:regular file(普通文件)、directory file(目录文件)、block special file(块特殊文件)、character special file(字符特殊文件)、FIFO(管道)、socket(套接字)、symbolic link(符号链接)。
这些文件类型可以用<sys/stat.h>中的宏定义来测试:
S_ISREG() —— 普通文件
S_ISDIR() —— 目录文件
S_ISBLK() —— 块特殊文件
S_ISCHR()——字符特殊文件
S_ISFIFO()——FIFO
S_ISSOCK()——套接字
S_ISLNK()——符号链接
3、读目录
#include <sys/types.h>
#include <dirent.h>
opendir函数的原型为:
DIR *opendir(const char *pathname);
它返回一个DIR*类型,这就是一个句柄啦,你不用管它的内部结构是什么样的,只要知道这个句柄就是等一下要传给readdir()函数的参数就行了。
readdir函数的原型为:
struct dirent *readdir(DIR *dir);
看它的参数就知道该参数是opendir函数返回的句柄,而该函数的返回值是struct dirent* 类型,这里我们必须了解一下这个结构体:
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 */
char d_name[256]; /* filename */
};
这个结构体的d_name存放的就是文件的名字,这里的文件包括普通文件,目录文件等
closedir函数的原型为:
int closedir(DIR *dir);
4、文件访问权限
在<sys/stat.h>有9个位的访问权限分别是S_IRUSR、S_IWUSR、S_IXUSR、S_IRGRP、S_IWGRP、S_IXGRP、S_IROTH、S_IWOTH、S_IXOTH
详细解释请观察下面程序例子即可。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <dirent.h> #include <unistd.h> #include <time.h> void printdir(char *dir,int depth){ DIR *dirp; struct stat statbuf; struct dirent *entry; if((dirp = opendir(dir)) == NULL){ fprintf(stderr,"Cannot open directory: %s\n",dir); return; } chdir(dir); while((entry = readdir(dirp)) != NULL){ lstat(entry->d_name,&statbuf); if(S_ISDIR(statbuf.st_mode)){ if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0) continue; putchar('d'); if(S_IRUSR & statbuf.st_mode) putchar('r');else putchar('-'); if(S_IWUSR & statbuf.st_mode) putchar('w');else putchar('-'); if(S_IXUSR & statbuf.st_mode) putchar('x');else putchar('-'); if(S_IRGRP & statbuf.st_mode) putchar('r');else putchar('-'); if(S_IWGRP & statbuf.st_mode) putchar('w');else putchar('-'); if(S_IXGRP & statbuf.st_mode) putchar('x');else putchar('-'); if(S_IROTH & statbuf.st_mode) putchar('r');else putchar('-'); if(S_IWOTH & statbuf.st_mode) putchar('w');else putchar('-'); if(S_IXOTH & statbuf.st_mode) putchar('x');else putchar('-'); printf(" %d %d %d",statbuf.st_uid,statbuf.st_gid,statbuf.st_size); printf(" %s ",ctime(&statbuf.st_mtime)); printf(" %d %s\n",depth,entry->d_name); printdir(entry->d_name,depth+1); }else{ putchar('-'); if(S_IRUSR & statbuf.st_mode) putchar('r');else putchar('-'); if(S_IWUSR & statbuf.st_mode) putchar('w');else putchar('-'); if(S_IXUSR & statbuf.st_mode) putchar('x');else putchar('-'); if(S_IRGRP & statbuf.st_mode) putchar('r');else putchar('-'); if(S_IWGRP & statbuf.st_mode) putchar('w');else putchar('-'); if(S_IXGRP & statbuf.st_mode) putchar('x');else putchar('-'); if(S_IROTH & statbuf.st_mode) putchar('r');else putchar('-'); if(S_IWOTH & statbuf.st_mode) putchar('w');else putchar('-'); if(S_IXOTH & statbuf.st_mode) putchar('x');else putchar('-'); printf(" %d %d %d",statbuf.st_uid,statbuf.st_gid,statbuf.st_size); printf(" %s ",ctime(&statbuf.st_mtime)); printf(" %d %s\n",depth,entry->d_name); } } chdir(".."); closedir(dirp); } int main(){ printdir("/home/xkey/APUE/3",0); return 0; }
5、access函数
#include <unistd.h>
int access(const char *pathname, int mode)
access函数按照实际用户ID和实际组ID进行访问权限测试
access函数中的mode常量取自<unistd.h>文件中,包括:R_OK(测试读权限)、W_OK(测试写权限)、X_OK(测试执行权限)、F_OK(测试文件是否存在)
6、umask函数
#include<sys/stat.h>
mode_t umask(mode_t cmask)
与unix指令中的umask一样
7、chmod和fchmod函数
#include<sys/stat.h>
int chmod(const char* pathname, mode_t mode)
int fchmod(int filedes, mode_t mode)
mode_t除了S_IRUSR、S_IWUSR、S_IXUSR、S_IRGRP、S_IWGRP、S_IXGRP、S_IROTH、S_IWOTH、S_IXOTH,还有S_ISUID、S_ISGID、S_ISVTX(粘住位即SBIT),SBIT只对目录有作用,其作用是:设置该SBIT那么该目录下的文件只能被自己或ROOT删除,可以cd /tmp 然后执行ls -al
8、chown、fchown、lchown函数
#include<unistd.h>
int chown(const char*pathname,uid_t owner, gid_t group)
int lchown(const char*pathname,uid_t owner, gid_t group)
int fchown(int filedes,uid_t owner, gid_t group)
函数的作用和unix指令中的chmod一样,但是lchown函数只对符号链接本身有用。
9、utime函数
#include <utime.h>
int utime(const char *pathname, const struct utimbuf *time)
获取文件的访问和修改时间即atime, mtime,没法获取ctime(文件更改时间,chmod、chown)
struct utimbuf{
time_t actime; /*access time*/
time_t modtime; /* modification time*/
};
本章还有其他一些函数,很简单就不列举,重点就是stat函数和文件的访问权限位。