linux 环境编程学习笔记 第七、八天 IO基础


寒假学习 第七、八天 (linux 高级编程) 笔记 小结

 

一、IO基础

1.认识内核对象

            系统不允许程序直接访问设备和内存,但可以通过内核系统函数去访问,系统对每个内核对象对象分配ID号。
程序要访问内核对象,只能通过ID号来访问。(申请得到一个ID ,在内核系统函数中使用ID得到对应内核对象数据)。
 

2.怎么访问文件

使用函数传递一个文件,系统打开文件,返回给程序ID号,程序通过ID号来访问文件,通过ID号来告诉系统释放文件。
(  ID:文件描述符号.file description (fd) )
 

3.每个程序默认打开三个文件设备

每个程序运行时 在/proc/ pid /fd / 下有三个 文件描述符号
 
lrwx------ 1 root root 64  1月 22 21:41 0 -> /dev/pts/4
lrwx------ 1 root root 64  1月 22 21:41 1 -> /dev/pts/4
lrwx------ 1 root root 64  1月 22 21:41 2 -> /dev/pts/4
 
他们都指向当前终端
但一般默认
                 0:标准输入
 1:标准输出
  2:错误输出
 
4.操作文件描述符号
 
ssize_t write(int fd,
	      void *buf,//要写入内核对象的数据
	      size_t size);//写入数据大小
返回:
	>0 实际写入的数据
	-1 写入错误	
ssize_t read(int fd,
	     void *buf,//返回数据的空间
	     size_t size);//空间大小
返回:
	>0:实际读取的数据
	=0:碰到文件结束符号EOF (ctrl+d)
	-1:读取错误

通过 write 跟 read 来访问
 

4、文件的类型 和 权限

文件类型
目录文件d
普通文件f
字符设备文件c
块设备文件b
软连接文件l
管道文件p
socket文件s
 
权限
rwx  就不多说了 
 
s/S
用来当程序执行时有s设置所设置的权限
  2:组设置位   设置位向其他用户开放拥有者权限的权限.用户设置位
  4:用户设置位  设置位向其他用户开放组用户权限的权限.组用户设置位
 
为什么分大小写见下面t/T中说的
 
t/T粘着位只针对目录有效
粘着位:一个文件可读写的用户并一定相让他有删除此文件的权限,如果文件设置了t权限则只用属主和root有删除文件的权限,通过chmod +t filename 来设置t权限。
因为 显示权限时 t/T 要占用 x 权限的位置 说以 用t 表示设置粘着位 并且 有 x 权限,T表示设置粘着位但 没有 有 x 权限。
 
详细的解释 http://hi.baidu.com/reyleon/item/e27650e588a1ce0a8e3ea891
 

5.通过文件描述符号读写各种数据

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);											

列子:
写入数据到stu.dat中去
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>

struct stu
{
	char name[20];
	int age;
	char c;
};

void input(struct stu* p_s)
{
	printf("Plase input:\n");
	printf("name:");
	scanf("%s",p_s->name);
	printf("age:");
	scanf("%d",&p_s->age);
	printf("sex:");
	getchar();
	scanf("%c",&p_s->c);
	getchar();
}

int main()
{
	int r=open("stu.dat",O_WRONLY|O_CREAT|O_EXCL,0666);
	struct stu s;
	char t;
	while(1)
	{
		input(&s);
		write(r,&s,sizeof(s));
		printf("Next?");
		scanf("%c",&t);
		if(t=='N'||t=='n'){
			break;
		}
		system("clear");
	}
	close(r);
}

读取stu.dat 中的数据
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>

struct stu
{
	char name[20];
	int age;
	char c;
};

int main()
{
	int r=open("stu.dat",O_RDONLY);
	int t;
	struct stu s;
	while(1)
	{
		t=read(r,&s,sizeof(s));
		printf("t=%d\n",t);
		if(t==0||t==-1) break;
		printf("%s\t%d\t%c\n",s.name,s.age,s.c);
	}
}
防止输出被重定向

1 用isatty函数
int isatty(int fd) 用来判定文件描述符号与终端的邦定关系
返回非0  fd输出终端 ,返回0  fd输出被重定向
 
2.可以用  /dev/tty
吧要输出的东西输出到  /dev/tty