系统编程(文件操作续)--C语言学习(3)

来源:互联网 发布:ubuntu maven m2 编辑:程序博客网 时间:2024/06/01 08:15

前述

今天总结一下文件操作,主要包括两部分,文件描述符的控制和my_ls的实现。

正文

1.对文件描述符进行控制操作以改变一打开文件的属性,fcntl函数原型如下

  int fcntl(int fd, int cmd);  int fcntl(int fd, int cmd, long arg );  int fcntl(int fd, int cmd, struct flock *flock);  struct flock{      short l_type;      short l_whence;      off_t l_start;      off_t l_len;      pid_t l_pid;      }

这里主要谈涉及到文件记录锁的第三种形式。

文件记录锁

文件记录锁是当多个进程同时对文件进行操作时,通过锁限制进程对文件的操作,比如读锁(F_RDLCK)允许一块文件内容多个进程同时读,而写锁(F_WRLCK)对一块文件内容只允许一个进程写。而两种所互不兼容,即对于一个字节只能存在一种类型的锁
此时cmd参数有三种形式:F_SETLK,F_SETLKW,F_GETLK.
1.F_SETLK 设置锁,我理解为按flock指向的结构体中的信息对fd进行设置
2.F_SETLKW 与上一条相似,但当希望设置的锁由于已经存在了其他锁而被阻止时,会等待直到那锁被释放。
3.F_GETLK 检测能否设置锁,如果可以将lock的l_type设置为F_UNLCK否则返回存在冲突的一种锁的结构。
当设置锁时,流程如下(以设置写锁为例)

struct flock lock;memset(&lock, 0, sizeof(struct flock)); //初始化结构体lock.l_type = F_WRLCK;//设置要写的属性包括whence等if((fcntl(fd, F_GETLK, lock)) == 0) //测试    {        if(lock -> l_type == F_UNLCK)        {            printf("lock can be set in fd\n");        }        else{            if(lock -> l_type == F_RDLCK)            printf("can't set lock ");            else if(lock -> l_type == F_WRLCK)            printf("can't set lock ");        }    }    else {        perror("get incompatible locks fail");        return -1    }    lock.l_type = F_WRLCK;    if((fcntl(fd, F_SETLK, lock)) == 0)    {        if(lock -> l_type == F_RDLCK)            printf("set read lock\n");        else if(lock -> l_type == F_WRLCK)            printf("set write lock \n");        else if(lock -> l_type == F_UNLCK)            printf("release lock\n",);    }    else {        perror("lock operation fail\n");        return -1;    }    return 0;

2.my_ls的实现
感觉并不是很难,但确实有一些地方做的不好。
下面以-Rl参数作为代表说一下
我的函数调用传递的形参为文件路径,用opendir函数打开要查看的目录,返回的dir指针再传递给readdir函数用来找到ptr指针,从而得到文件名,再有文件名通过stat函数读取文件信息存放在结构体数组file中,因为结构体stat中没有成员变量保存文件名,于是我又定义了一个指针数组用来记录文件名,也方便对文件名排序。

int my_readir_rl(const char *path){    DIR *dir;    char dir_name[100][50];    struct dirent *ptr;    int i = 0,tem,key =0;;    /*用路径打开目录*/    if((dir = opendir(path)) == NULL)    {        perror("opendir");        return -1;    }    /*将进程的当前工作目录转换为要查看的目录*/    chdir(path);    printf("----------------- %s------------------\n",path);    //通过ptr获取文件名    while((ptr = readdir(dir)) != NULL&&i < 99)    {        //不读取隐藏文件及目录        if((ptr -> d_name)[0] == '.')        continue;        //获取文件信息存入结构体数组        stat(ptr -> d_name, &file[i]);        //记录文件名        name[i] = ptr -> d_name;        //判断当前文件是否为一个目录        if((tem = (file[i].st_mode /512)) == 32)        {            //获取当前目录绝对路径            getcwd(dir_name[key],512);            //将子目录的目录名补全为绝对路径记录在dirname数组中            strcat(dir_name[key],"/");            strcat(dir_name[key], name[i]);            key++;        }        i++;       }    //按照文件名进行排序    bubble_sort(i);    //将文件权限由mode_t转换为rwx的字符串    change_mode_t(i);    //打印信息    print(i);    //将之前记录的子目录绝对路径再次调用函数读取显示信息    for(tem =0; tem < key; tem++)    {        my_readir_rl(dir_name[tem]);    }    return 0;}

没有采用链表的数据结构,导致并不能显示太多的文件信息。

0 0