zoukankan      html  css  js  c++  java
  • UNIX环境高级编程——文件和目录

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

    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
    ");
            break;
        case S_IFLNK:
            printf("symbolic link
    ");
            break;
        case S_IFREG:
            printf("regular file
    ");
            break;
        case S_IFBLK:
            printf("block device
    ");
            flag = 1;
            break;
        case S_IFDIR:
            printf("directory
    ");
            break;
        case S_IFCHR:
            printf("character device
    ");
            flag = 1;
            break;
        case S_IFIFO:
            printf("FIFO
    ");
            break;
        default:
            printf("unknown file type
    ");
            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] = '';
    }
    
    
    int main(int argc, char *argv[])
    {
        if (argc != 2)
        {
            fprintf(stderr, "Usage %s file
    ", argv[0]);
            exit(EXIT_FAILURE);
        }
    
        printf("Filename:%s
    ", argv[1]);
        struct stat sbuf;
        if (lstat(argv[1], &sbuf) == -1)
            ERR_EXIT("stat error");
    
        printf("file in Dev number:major %d, minor %d
    ",
               MAJOR(sbuf.st_dev), MINOR(sbuf.st_dev));
        printf("File inode:%d
    ", (int) sbuf.st_ino);
    
        if (filetype(&sbuf))
        {
            printf("Device number:major %d, minor %d
    ",
                   MAJOR(sbuf.st_rdev), MINOR(sbuf.st_rdev));
        }
    
        char perm[11] = {0};
        fileperm(&sbuf, perm);
        printf("File permission bits=%o %s
    ", sbuf.st_mode & 07777, perm);
    
        return 0;
    }
    测试如下:

    huangcheng@ubuntu:~$ ./a.out hc
    Filename:hc
    file in Dev number:major 8, minor 1
    File inode:929485
    Filetype:regular file
    File 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
    ", 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 分配,但是这种情况要特别注意使用后释放缓冲以防止内存泄漏。

  • 相关阅读:
    信号
    序列化数据的两种方式
    ModelForm的使用
    分页模板
    Django中间件进行用户登陆验证
    Flask 笔记一
    pipenv 使用基本命令
    git本地文件 上传 远程仓库
    service "$service" status 返回的状态
    &>/dev/null 的作用
  • 原文地址:https://www.cnblogs.com/wangfengju/p/6172844.html
Copyright © 2011-2022 走看看