三.基于文件的描术符号
1.得到文件描术符号/释入文件描术符号
a.文件类型
目录文件 d
普通文件 f
字符设务文件 c
块设备文件 b
软连接文件 l
管道文件 p
socket文件 s
字符设备文件:
[root@monitor ~]# ls -l /dev/console
crw------- 1 root root 5, 1 May 16 21:36 /dev/console
块设备文件 :
[root@monitor ~]# ls -l /dev/xvda1
brw-rw---- 1 root disk 202, 1 May 16 21:36 /dev/xvda1
管道文件:
mkfifo p.pipe
[root@monitor ~]# ll p.pipe
prw-r--r-- 1 root root 0 May 24 16:42 p.pipe
socket文件
[root@monitor ~]# 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
[root@monitor ~]# chmod 01000 p.pipe
[root@monitor ~]# ll p.pipe
p--------T 1 root root 0 May 24 16:42 p.pipe
[root@monitor ~]# chmod 01001 p.pipe
[root@monitor ~]# ll p.pipe
p--------t 1 root root 0 May 24 16:42 p.pipe
[root@monitor ~]# chmod 02000 p.pipe
[root@monitor ~]# ll p.pipe
p-----S--- 1 root root 0 May 24 16:42 p.pipe
[root@monitor ~]# chmod 02010 p.pipe
[root@monitor ~]# ll p.pipe
p-----s--- 1 root root 0 May 24 16:42 p.pipe
[root@monitor ~]# chmod 04000 p.pipe
[root@monitor ~]# ll p.pipe
p--S------ 1 root root 0 May 24 16:42 p.pipe
[root@monitor ~]# ll p.pipe
p--S------ 1 root root 0 May 24 16:42 p.pipe
[root@monitor ~]# chmod 04100 p.pipe
[root@monitor ~]# ll p.pipe
p--s------ 1 root root 0 May 24 16:42 p.pipe
[root@monitor ~]# chmod a+s p.pipe
[root@monitor ~]# ll p.pipe
p--s--S--- 1 root root 0 May 24 16:42 p.pipe
[root@monitor ~]# chmod a+st p.pipe
[root@monitor ~]# 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:
结构体读取
描述:从键盘读取若干条数据,保存到文件
数据追加
View Code
#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 存在的文件 新的文件名
要求:
文件存在就拷贝,不存在提示错误.