系统编程(文件操作续)--C语言学习(3)
2016-07-20 22:56
288 查看
前述
今天总结一下文件操作,主要包括两部分,文件描述符的控制和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; }
没有采用链表的数据结构,导致并不能显示太多的文件信息。
相关文章推荐
- C语言实现判断闰年、从常规时间到卫星系统时间的转换
- 大话设计模式04----开放-关闭原则
- GDB 调试 C++ 程序 core dump
- C++中交换值与比较值的另类实现方式
- C++基础:派生类的构造函数与析构函数调用顺序
- C++ 处理文件结束符的两种不同方式
- C++基础:继承访问属性
- 图书管理系统(c语言课程设计)
- C++提高5 STL算法 :查找,统计,排序,拷贝,替换,算术,集合 |STL 案例:学校演讲比赛介绍
- 备忘录模式-c++实现
- 大话设计模式03----单一职责原则
- 已知先序、中序求后序;已知中序、后序求先序(C++)
- 大数运算模板(C语言)
- 动态规划的思考(三)
- 代刷题目分类(二)
- 大话设计模式02----商场促销-策略模式
- Combinations
- C++中关于堆和栈的说法,哪个是错误的:
- C++ Learning (1)
- C++不是类型安全的语言