UNIX环境高级编程——文件和目录

来源:互联网 发布:淘宝改中差评 编辑:程序博客网 时间:2024/05/18 02:03

一、获取文件/目录的属性信息

int stat(const char *path, struct stat *buf);int fstat(int fd, struct stat *buf);int lstat(const char *path, struct stat *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 */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 */};
示例程序:

#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<fcntl.h>#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#define ERR_EXIT(m) \    do { \        perror(m); \        exit(EXIT_FAILURE); \    } while(0)#define MAJOR(a) (int)((unsigned short)a >> 8)  // 高8位,主设备号#define MINOR(a) (int)((unsigned short)a & 0xFF)int filetype(struct stat *buf){    int flag = 0;    printf("Filetype:");    mode_t mode;    mode = buf->st_mode;    switch (mode & S_IFMT)    {    case S_IFSOCK:        printf("socket\n");        break;    case S_IFLNK:        printf("symbolic link\n");        break;    case S_IFREG:        printf("regular file\n");        break;    case S_IFBLK:        printf("block device\n");        flag = 1;        break;    case S_IFDIR:        printf("directory\n");        break;    case S_IFCHR:        printf("character device\n");        flag = 1;        break;    case S_IFIFO:        printf("FIFO\n");        break;    default:        printf("unknown file type\n");        break;    }    return flag;}void fileperm(struct stat *buf, char perm[]){    strcpy(perm, "----------");    perm[0] = '?';    mode_t mode;    mode = buf->st_mode;    switch (mode & S_IFMT)    {    case S_IFSOCK:        perm[0] = 's';        break;    case S_IFLNK:        perm[0] = 'l';        break;    case S_IFREG:        perm[0] = '-';        break;    case S_IFBLK:        perm[0] = 'b';        break;    case S_IFDIR:        perm[0] = 'd';        break;    case S_IFCHR:        perm[0] = 'c';        break;    case S_IFIFO:        perm[0] = 'p';        break;    }    if (mode & S_IRUSR)        perm[1] = 'r';    if (mode & S_IWUSR)        perm[2] = 'w';    if (mode & S_IXUSR)        perm[3] = 'x';    if (mode & S_IRGRP)        perm[4] = 'r';    if (mode & S_IWGRP)        perm[5] = 'w';    if (mode & S_IXGRP)        perm[6] = 'x';    if (mode & S_IROTH)        perm[7] = 'r';    if (mode & S_IWOTH)        perm[8] = 'w';    if (mode & S_IXOTH)        perm[9] = 'x';    perm[10] = '\0';}int main(int argc, char *argv[]){    if (argc != 2)    {        fprintf(stderr, "Usage %s file\n", argv[0]);        exit(EXIT_FAILURE);    }    printf("Filename:%s\n", argv[1]);    struct stat sbuf;    if (lstat(argv[1], &sbuf) == -1)        ERR_EXIT("stat error");    printf("file in Dev number:major %d, minor %d\n",           MAJOR(sbuf.st_dev), MINOR(sbuf.st_dev));    printf("File inode:%d\n", (int) sbuf.st_ino);    if (filetype(&sbuf))    {        printf("Device number:major %d, minor %d\n",               MAJOR(sbuf.st_rdev), MINOR(sbuf.st_rdev));    }    char perm[11] = {0};    fileperm(&sbuf, perm);    printf("File permission bits=%o %s\n", sbuf.st_mode & 07777, perm);    return 0;}
测试如下:

huangcheng@ubuntu:~$ ./a.out hcFilename:hcfile in Dev number:major 8, minor 1File inode:929485Filetype:regular fileFile permission bits=644 -rw-r--r--

二、目录的访问

功能说明:打开一个目录
原型:DIR*  opendir(char *pathname);

返回值:
打开成功,返回一个目录指针
打开失败,则返回NULL


功能说明:访问指定目录中下一个连接的细节
原型:struct  dirent*  readdir(DIR  *dirptr);

返回值:
返回一个指向dirent结构的指针,它包含指定目录中下一个连接的细节;
没有更多连接时,返回NULL


功能说明:关闭一个已经打开的目录
原型:int closedir (DIR  *dirptr);

返回值:调用成功返回0,失败返回-1


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 supported                                              by all file system types */               char      d_name[256]; /* filename */ };

三、目录的创建删除和权限设置

功能说明:用来创建一个称为pathname的新目录,它的权限位设置为mode
原型:int  mkdir(char *pathname,mode_t mode);

返回值:调用成功返回0,失败返回-1


功能说明:删除一个空目录
原型:int  rmdir(char *pathname);

返回值:调用成功返回0,失败返回-1


功能说明:用来改变给定路径名pathname的文件的权限位。为了改变一个文件的权限位,进程的有效用户ID必须等于文件的所有者ID,或者该进程必须具有超级用户的权限。
原型:int  chmod (char *pathname, mode_t mode);

int  fchmod (int  fd, mode_t mode);

返回值:调用成功返回0,失败返回-1


功能说明:用来改变文件所有者的识别号(owner id)或者它的用户组识别号(group ID),如若两个参数owner或group中的任意一个为-1,则对应的ID不变。
原型:int  chown (char *pathname, uid_t owner,gid_t group);

int  fchown (int  fd, uid_t owner,gid_t group);

返回值:调用成功返回0,失败返回-1

示例代码:

#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<fcntl.h>#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<dirent.h>#define ERR_EXIT(m) \    do { \        perror(m); \        exit(EXIT_FAILURE); \    } while(0)int main(int argc, char *argv[]){    DIR *dir = opendir(".");    struct dirent *de;    while ((de = readdir(dir)) != NULL)    {        if (strncmp(de->d_name, ".", 1) == 0)            continue; //忽略隐藏文件        printf("%s\n", de->d_name);    }    closedir(dir);    exit(EXIT_SUCCESS); // 等价于return 0}

四、文件长度
     stat结构成员st_size表示以字节为单位的文件长度。此字段只对普通文件、目录文件盒符号链接有意义。
     对于普通文件,其文件长度可以是0,在读这种文件时,将得到文件结束指示。
     对于目录,文件长度通常是一个数(例如512)的倍数。

     对于符号链接,文件长度是文件名中的实际字节数(即huangcheng的符号链接为10,不包括c语言用作名字结尾的null字符)


五、文件截短

int truncate(const char *path, off_t length);int ftruncate(int fd, off_t length);
    这两个函数将把现有的文件长度截短length字节。如果该文件以前的长度大于length,则超过length以外的数据就被删除。


六、chdir、fchdir和getcwd函数

     每个进程都有一个当前目录,此目录是搜索所有相对路径名的起点。当前工作目录是进程的一个属性,起始目录则是登陆名(/etc/passwd)的一个属性。

int chdir(const char *path);int fchdir(int fd);

    这两个函数中,分别用path或打开文件描述符指定新的当前工作目录。


char *getcwd(char *buf, size_t size);

    把当前目录的绝对地址保存到 buf 中,buf 的大小为 size。如果 size太小无法保存该地址,返回 NULL 并设置 errno 为 ERANGE。可以采取令 buf 为 NULL并使 size 为负值来使 getcwd 调用 malloc 动态给 buf 分配,但是这种情况要特别注意使用后释放缓冲以防止内存泄漏。

原创粉丝点击