三.基于文件的描术符号 1.得到文件描术符号/释入文件描术符号 a.文件类型 目录文件 d 普通文件 f 字符设务文件 c 块设备文件 b 软连接文件 l 管道文件 p socket文件 s 字符设备文件: [[email protected] ~]# ls -l /dev/console crw------- 1 root root 5, 1 May 16 21:36 /dev/console 块设备文件 : [[email protected]or ~]# ls -l /dev/xvda1 brw-rw---- 1 root disk 202, 1 May 16 21:36 /dev/xvda1 管道文件: mkfifo p.pipe [[email protected] ~]# ll p.pipe prw-r--r-- 1 root root 0 May 24 16:42 p.pipe socket文件 [[email protected] ~]# ll /var/lib/mysql/mysql.sock srwxrwxrwx 1 mysql mysql 0 Apr 11 13:12 /var/lib/mysql/mysql.sock b.文件的属性 1.属性的表达方式:绝对模式,字符模式 2.文件的权限属性: 读 写 执行 粘附位权限 用户设置位权限 0 0 0 0 0 特殊权限 OWNER group 其他用户 chmod 0000 p.pipe p--------- 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# chmod 01000 p.pipe [[email protected] ~]# ll p.pipe p--------T 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# chmod 01001 p.pipe [[email protected] ~]# ll p.pipe p--------t 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# chmod 02000 p.pipe [[email protected] ~]# ll p.pipe p-----S--- 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# chmod 02010 p.pipe [[email protected] ~]# ll p.pipe p-----s--- 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# chmod 04000 p.pipe [[email protected] ~]# ll p.pipe p--S------ 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# ll p.pipe p--S------ 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# chmod 04100 p.pipe [[email protected] ~]# ll p.pipe p--s------ 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# chmod a+s p.pipe [[email protected] ~]# ll p.pipe p--s--S--- 1 root root 0 May 24 16:42 p.pipe [[email protected] ~]# chmod a+st p.pipe [[email protected] ~]# ll p.pipe p--s--S--T 1 root root 0 May 24 16:42 p.pipe s:S:t:T: 1.1. s设置位 2:组设置位 4:用户设置位 s对执行有效 无效的设置位使用S表示 设置位:向其他用户开放拥有者权限的权限:用户设置位 向其他用户开放组有户权限的权限:组用户设置位 设置位只对执行程序有意义(执行权限有意义) 程序在执行的时候到底拥有的是 执行者 用户权限,还是 文件拥有者 的权限???? 有设置位:文件拥有者的权限,程序执行过程中 无设置位:执行者用户权限,程序执行过程中 程序执行有两个用户: 实际用户:标示进程到底是谁 有效用户:标示进程访问资源的权限 上述一般情况是一样的,有时候被setUID改变 总结: 沾附位的作用: 防止其他有写权限用户删除文件 设置位的作用: 向其他执行者开发组或者用户的权限 2.1. t设置位 表示沾附位设置 t对写文件有意义 无效的沾附位使用T表示. 沾附的目的:防止有些权限的用户删除文件 eg: cat /etc/shadow cat /etc/password password eg: 赵: main rwx a.txt wr 张三:main x a.txt r 张三可以执行main,但对a.txt 只读权限?? 练习: 1.使用cat创建一个文件 2.设置沾附位,并观察属性 3.设置用户设置位, 并观察属性 4.设置组设置位, 并观察属性 5.考虑w权限与沾附位的关系 6.考虑x权限与设置位的关系. 2.通过文件描述符号读写各种数据. open函数与creat函数 int open( const char *filename,//文件名 int flags,//open的方式[创建/打开] mode_t mode//权限(只有创建的时候有效) ) 返回: >=0:内核文件描述符号. =-1:打开/创建失败 open的方式: 必选方式:O_RDONLY O_WRONLY O_RDWR,必须选择一个 创建/打开:O_CREAT 可选方式: 对打开可选方式:O_APPEND O_TRUNC(清空数据) 对创建可选方式:O_EXCL 组合: 创建: O_RDWR|O_CREAT O_RDWR|O_CREAT | O_EXCL 打开: O_RDWR O_RDWR|O_APPEND O_RDWR|O_TRUNC 权限: 建议使用8进制数 关闭 void close(int fd); 案例1: 创建文件 案例2: 创建文件并写入数据 20 short float tom 20 99.99 bush 70 65.00 达内 40 100.00 注意: 文件的创建的权限受系统的权限屏蔽的影响 umask //显示屏蔽权限. umask 0666 //设置权限屏蔽. ulimit -a 显示所有的其他限制. /*创建文件*/ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> main() { int fd; char name[20]; short age; float score; char sex; fd=open("test.dat", O_RDWR|O_CREAT|O_EXCL, ); if(fd==-1) printf("open error:%m\n"),exit(-1); //写第一条 memcpy(name,"tom",strlen("tom")+1); age=20; score=99.99; sex=‘F‘; write(fd,name,sizeof(name)); write(fd,&age,sizeof age); write(fd,&score,sizeof(float)); write(fd,&sex,sizeof(sex)); //写第二条 memcpy(name,"Bush",strlen("Bush")+1); age=70; score=65.00; sex=‘M‘; write(fd,name,sizeof(name)); write(fd,&age,sizeof age); write(fd,&score,sizeof(float)); write(fd,&sex,sizeof(sex)); //写第三条 memcpy(name,"达内",strlen("达内")+1); age=10; score=99.00; sex=‘F‘; write(fd,name,sizeof(name)); write(fd,&age,sizeof age); write(fd,&score,sizeof(float)); write(fd,&sex,sizeof(sex)); close(fd); } 案例3: 打开文件读取数据 重点: 怎么打开读取 文件尾的判定 基本类型的数据读写. #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> main() { char name[20]; short age; float score; char sex; int fd; int r; fd=open("test.dat",O_RDONLY); if(fd==-1) printf("open error:%m\n"),exit(-1); while(1) { r=read(fd,name,sizeof(name)); if(r==0) break; r=read(fd,&age,sizeof(short)); r=read(fd,&score,sizeof(float)); r=read(fd,&sex,sizeof(sex)); printf("%s,\t%4hd,\t%.2f,\t%1c\n", name,age,score,sex); } close(fd); } 案例4: 结构体读取 描述:从键盘读取若干条数据,保存到文件 数据追加 #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> struct stu { int no; char name[20]; float score; }; /* .判定文件是否存在,存在打开,不存在创建 .输入记录 .保存记录 .提示继续输入 .继续/不继续 .关闭文件 */ int openfile(const char *filename) { int fd; fd=open(filename,O_RDWR|O_CREAT|O_EXCL,0666); if(fd==-1)//表示文件存在,则打开 { fd=open(filename,O_RDWR|O_APPEND); return fd; } return fd; } void input(struct stu *record) { bzero(record,sizeof(struct stu)); printf("输入学号:"); scanf("%d",&(record->no)); printf("输入姓名:"); scanf("%s",record->name); printf("输入成绩:"); scanf("%f",&(record->score)); } void save(int fd,struct stu *record) { write(fd,record,sizeof(struct stu)); } int iscontinue() { char c; printf("是否继续输入:\n"); //fflush(stdin); //fflush(stdout); scanf("\n%c",&c); if(c==‘Y‘ || c==‘y‘) { return 1; } return 0; } int main() { int fd; int r; struct stu s={0}; fd=openfile("stu.dat"); if(fd==-1) printf("openfile:%m\n"),exit(-1); while(1) { input(&s); save(fd,&s); r=iscontinue(); if(r==0) break; system("clear"); } close(fd); printf("输入完毕!\n"); } 3.文件描述符号与重定向 1.判定文件描述符号与终端的邦定关系 int isatty(int fd) 返回非0:fd输出终端 0:fd输出被重定向 2.防止重定向 /dev/tty #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> int main() { int fd; printf("Hello\n"); write(1,"World\n",6); fd=open("/dev/tty",O_WRONLY); if(isatty(1)) { write(1,"notredir\n",9); } else { write(1,"redir\n",6); } write(fd,"Killer\n",7); } 总结: 1.make的多目标依赖规则以及伪目标 2.文件的创建与打开(了解设置位的作用) 3.文件的读写(字符串/基本类型/结构体) 4.了解描述符号与重定向 作业: 1.完成上课的练习. 2.写一个程序使用结构体读取1种的数据, 并全部打印数据, 并打印平均成绩 3.写一个程序: 查询1种的数据.比如:输入姓名,查询成绩 4.写一个程序,录入保存如下数据: 书名 出版社 价格 存储量 作者 5.写一个程序负责文件拷贝 main 存在的文件 新的文件名 要求: 文件存在就拷贝,不存在提示错误.
时间: 2024-10-24 00:03:37