第三章:文件系统

来源:互联网 发布:中信淘宝v卡线上办理 编辑:程序博客网 时间:2024/05/16 09:17
Linux C 高级程序员指南
国防工业出版社

第三章:文件系统

函数getcwd用于得到当前工作目录的路径名
     #include<unistd.h>
     char* getcwd(char* buf,size_t size);

buf为缓冲地址,size为最到路径长度
eg.
/*输出当前的工作目录的路径名*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifndef MAX_PATH
#define MAX_PATH 255
#endif

int main(void) {
    char name[MAX_PATH + 1];
    if(getcwd(name, MAX_PATH) == NULL){
        printf("error:getcwd/n");
        exit(1);
    }
    printf("Current working directory is : %s/n", name);
    exit(0);
}

读取目录用到opendir,readdir,rewinddir,closedir函数
    #include <sys/types.h>
    #include <dirent.h>
    DIR* opendir(const char* dirname);
    struct dirent* readdir(DIR* dirp);
    void rewinddir(DIR* dirp);
    int closedir(DIR* dirp);

    struct dirent
    {
        ino64_t d_ino;
        off64_t d_off;
        unsigned short int d_reclen;
        unsigned char d_type;
        char d_name[256];
    }

eg.
/*列出指定目录下的所有文件和子目录*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>

int main(int argc, char** argv) {
    DIR *dirp;
    struct dirent *direntp;
    if(argc != 2){
        printf("Usage:%s dirname/n", argv[0]);
        exit(1);
    }
    if((dirp = opendir(argv[1])) == NULL){
        printf("Can't open directory : %s/n", argv[1]);
        exit(1);
    }
    while((direntp = readdir(dirp)) != NULL){
        printf("%s /n", direntp->d_name);
    }
    closedir(dirp);
    exit(0);
}

在linux系统中,用16位字段表示该文件的的属性,用户,用户组标识以及存储权限
15        S_IFREG                    一般文件
14        S_IFDIR                    目录
13        S_IFCHAR/S_IFBLK        字符或块设备文件
12        S_IFIFO                    命名管道
11        S_ISUID                    用户标识是否被设定
10        S_ISGID                    用户组标识是否被设定
9        S_ISVTX                    是否被置换
0-8    rwx-rwx-rwx                文件存取权限(依次为所有者,同组用户,其他用户)

函数stat和fstat可以得到文件的信息
    #include <sys/stat.h>
    int stat(const char* file, struct stat* buf);
    int fstat(int fd,struct stat* buf);
函数成功则返回0,否则返回-1
struct stat
{
    dev_t st_dev;        /*Device*/
    ino_t st_ino;        /*File serial number*/
    mode_t st_mode;    /*File mode*/
    nlink_t st_nlink;    /*Link count*/
    uid_t    st_uid;        /*User ID of file's owner*/
    gid_t st_gid;        /*Group ID of the file's group*/
    dev_t st_rdev;        /*Device number,if is device*/
    off_t st_size;        /*Size of file, 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 staus change*/
}

eg.
/*程序用于显示文件的信息*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <time.h>

void Usage(char* name){
    printf("Usage: %s filename", name);
    exit(1);
}

int main(int argc, char* argv[]) {
    struct stat st;
    int isdevice = 0;
    if(argc != 2)
        Usage(argv[0]);
    if(stat(argv[1], &st) == -1){
        printf("error:stat/n");
        exit(1);
    }
    if((st.st_mode & S_IFMT) == S_IFDIR)/*S_IFMT == 0170000(oct)*/
        printf("type:Directory/n");
    else if((st.st_mode & S_IFMT) == S_IFBLK){
        printf("type: Block special file/n");
        isdevice = 1;
    }
    else if ((st.st_mode & S_IFMT) == S_IFCHR){
        printf("type:Character special file/n");
        isdevice = 1;
    }
    else if ((st.st_mode & S_IFMT) == S_IFREG)
        printf("type:Ordinary file/n");
    else if ((st.st_mode & S_IFMT) == S_IFIFO)
        printf("type: FIFO(named pipe)/n");
   
    if (isdevice)
        printf("Device number: %d, %d/n", (int)(st.st_rdev >> 8) & 0xff, (int)st.st_rdev & 0xff);
   
    printf("Resides device: %d,%d/n", (int)(st.st_dev >> 8) & 0xff, (int)st.st_rdev & 0xff);
    printf("l-node: %d, links: %d, size: %ld/n", (int)st.st_ino, st.st_nlink, st.st_size);
    printf("Owner ID: %d, group ID: %d/n", st.st_uid, st.st_gid);
    printf("Permission:%o/n",st.st_mode & 0x1ff);
    printf("Last access: %15s", ctime(&st.st_atime));
    printf("Last modification: %15s", ctime(&st.st_mtime));
    printf("Last inode change: %15s", ctime(&st.st_ctime));
    exit(0);
}


下面给出一个综合的程序,用来打印所有的指定目录下的文件名以及子目录下的文件名
/*程序给出的指定目录下的所有文件包括子目录中的文件*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>

void Usage(char* name){
    printf("Usage: %s filename", name);
    exit(1);
}

int dirwalk(char* dirname){
    char filename[256];
    DIR *dirp;
    struct dirent* direntp;
    struct stat st;
   
    if ((dirp = opendir(dirname)) == NULL){
        printf("Could not open directory: %s/n", dirname);
        /*exit(1);*/
        return 0;
    }
   
    while((direntp = readdir(dirp)) != NULL){
        strcpy(filename, dirname);
        if(filename[strlen(filename) -1] != '/')
            strcat(filename, "/");
       
        if((strcmp(direntp->d_name, ".") != 0) && strcmp(direntp->d_name, "..") != 0){
            strcat(filename, direntp->d_name);
           
            if(stat(filename, &st) == -1){
                printf("error:stat/n");
                /*exit(1);*/
                continue;
            }
            if((st.st_mode & S_IFMT) == S_IFDIR)
                dirwalk(filename);
            else
                printf("%s/n", filename);
        }
    }
    closedir(dirp);
}



int main(int argc, char* argv[]) {
    if(argc != 2)
        Usage(argv[0]);
   
    dirwalk(argv[1]);
   
    exit(0);
}

函数getpwuid和getpwnam用于得到用户的信息
    #include <pwid.h>
    struct passwd* getpwuid(uid_t uid);
    struct passwd* getpwnam(const char* name);
两个函数分别以用户的ID和用户名为参数,返回struct passwd的结构体
struct passwd
{
    char* pw_name;            /*Username*/
    char* pw_password;    /*user's password after encrypted*/
    uid_t pw_uid;            /*User ID*/
    gid_t pw_gid;            /*Group ID*/
    char* pw_gecos;        /*Real name*/
    char* pw_dir;            /*Home directory*/
    char* pw_shell;        /*Shell program*/
}
函数getgrgid和getgrnam用于得到用户组的信息
    #include <grp.h>
    struct group* getgrid(gid_t gid);
    struct group* getgrnam(const char* name);
两个函数分别以用户组的ID和用户组名为参数,返回struct passwd的结构体
struct group
{
    char* gr_name;            /*Group name*/
    char* gr_passwd;        /*Group password after encrypted*/
    gid_t gr_gid;            /*Group ID*/
    char** gr_mem;            /*Member list*/
}
eg.
/*程序用于获取用户以及用户组的信息*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>

void Usage(char* name){
    printf("Usage: %s filename", name);
    exit(1);
}

int main(int argc, char* argv[]) {
    struct passwd* pwd;
    struct group* grp;
    char** namelist;
    int i;
   
    if(argc != 2)
        Usage(argv[0]);
   
    if((pwd = getpwnam(argv[1])) == NULL){
        if((pwd = getpwuid(atoi(argv[1]))) == NULL){
            printf("error: user name or user ID not exist./n");
            exit(1);
        }
    }
   
    printf("User name: %s/n", pwd->pw_name);
    printf("User password: %s/n", pwd->pw_passwd);
    printf("User ID : %d/n", pwd->pw_uid);
    printf("User GID : %d/n", pwd->pw_gid);
    printf("User real name : %s/n", pwd->pw_gecos);
    printf("User Dir : %s/n", pwd->pw_dir);
    printf("User shell : %s/n", pwd->pw_shell);
   
    if((grp = getgrgid(pwd->pw_gid)) == NULL){
        printf("error: getgrgid/n");
        exit(1);
    }
   
    printf("Group name : %s/n", grp->gr_name);
    printf("Group password : %s/n", grp->gr_passwd);
    printf("Group mamber : ");
    namelist = grp->gr_mem;
    for(i = 0; namelist[i] != NULL;i++)
        printf("/t%s/n", namelist[i]);
   
    exit(0);
}

函数ustat用于获取设备上安装的文件系统信息
    #include<sys/ustat.h>
    int ustat(dev_t dev, struct ustat* ubuf);
dev为设备号,ubuf指向结构体指针
struct ustat
{
    daddr_t f_tfree;            /*free buffer number*/
    ino_t f_tinode;            /*free node number*/
    char f_fname[6];            /*file system name*/
    char f_fpack[6];            /*file system device name*/
}
eg.
/*程序用于获取文件系统信息*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ustat.h>

void Usage(char* name){
    printf("Usage: %s filename", name);
    exit(1);
}


int main(int argc, char* argv[]) {
    struct ustat ubuf;
   
    if(argc != 2)
        Usage(argv[0]);
   
    if(ustat(atoi(argv[1]), &ubuf) == -1){
        printf("Could not ustat file system on device %s/n", argv[1]);
        exit(1);
    }
   
    printf("The totel number of free space is %d/n", ubuf.f_tfree);
    printf("The totel number of i_nodes is %d/n", (int)ubuf.f_tinode);
    printf("The fsname is %6s, the pack name is %6s/n", ubuf.f_fname, ubuf.f_fpack);
   
    exit(0);
}


系统调用statfs和fstatfs用于将文件系统的信息存入statfs结构体中
    #include <sys/statfs.h>
    int statfs(const char* file, struct statfs* buf);
    int fstatfs(int fd, struct statfs* buf);
file为文件系统所在的设备文件的路径,fd则为文件系统所在的设备文件相对应的文件描述符
struct statfs
{
    int f_type;                    /*file type*/
    int f_bsize;                /*block size*/
    fsblkcnt_t f_blocks;        /*number of blocks*/
    fsblkcnt_t f_bfree;        /*number of free blocks*/
    fsblkcnt_t f_bavail;        /*number of available blocks*/
    fsfilcnt_t f_files;        /*the i node number*/
    fsfilcnt_t f_ffree;        /*free i node number*/
    fsid_t f_sid;                /*specify of the file system*/
    int f_namelen;                /*file system name*/
    int f_spare[6];            /*spare name*/
}
eg.
/*程序用于获取文件系统信息*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ustat.h>

void Usage(char* name){
    printf("Usage: %s filename", name);
    exit(1);
}


int main(int argc, char* argv[]) {
    struct ustat ubuf;
   
    if(argc != 2)
        Usage(argv[0]);
   
    if(ustat(atoi(argv[1]), &ubuf) == -1){
        printf("Could not ustat file system on device %s/n", argv[1]);
        exit(1);
    }
   
    printf("The totel number of free space is %d/n", ubuf.f_tfree);
    printf("The totel number of i_nodes is %d/n", (int)ubuf.f_tinode);
    printf("The fsname is %6s, the pack name is %6s/n", ubuf.f_fname, 0ubuf.f_fpack);
   
    exit(0);
}


    
原创粉丝点击