APUE学习笔记——第四章 文件和目录

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函数和文件的访问权限位。

发布了101 篇原创文章 · 获赞 26 · 访问量 46万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览