2、设备和文件IO

上传人:ahu****ng1 文档编号:146130670 上传时间:2020-09-27 格式:PPTX 页数:43 大小:596.33KB
返回 下载 相关 举报
2、设备和文件IO_第1页
第1页 / 共43页
2、设备和文件IO_第2页
第2页 / 共43页
2、设备和文件IO_第3页
第3页 / 共43页
2、设备和文件IO_第4页
第4页 / 共43页
2、设备和文件IO_第5页
第5页 / 共43页
点击查看更多>>
资源描述

《2、设备和文件IO》由会员分享,可在线阅读,更多相关《2、设备和文件IO(43页珍藏版)》请在金锄头文库上搜索。

1、第二章设备和文件IO,本章目标,理解设备和文件的关系 理解系统调用和系统API等关系,掌握系统调用的工作过程 掌握系统调用open/read/write/fcntl等使用,Linux中的设备管理,Linux设备管理概述 在Linux系统中,用户是通过文件系统与设备接口的。所有设备都作为特别文件,从而在设备管理上具有下列特性。 (1)每个设备都对应文件系统中的一个索引节点,都有一个文件名。,(2)应用程序通常可以通过系统调用open()打开设备文件,建立起与目标设备的连接。 (3)对设备的使用类似于对文件的存取。 (4)设备驱动程序都是系统内核的一部分,它们必须为系统内核或者它们的子系统提供一个

2、标准的接口。 (5)设备驱动程序使用一些标准的内核服务,如内存分配等。,设备工作原理,设备分类,按设备属主关系 系统设备 用户设备 按设备信息交换单位来分 字符设备 块设备 按设备共享属性来分 独享设备 共享设备,Linux设备操作,设备或文件操作两种方式: 用户编程接口 API 系统调用,系统调用,系统调用是操作系统提供给用户的一组“特殊”接口 系统调用并非直接和程序员或系统管理员直接打交道,而是通过软中断的方式向内核提交请求,从而获取内核函数的服务入口(系统调用表) 系统调用让系统从用户空间进入内核空间内运行,运行后将结果返回给应用程序(内核态-用户空间),系统调用和系统API等区别,系统

3、API 主要是通过C库libc来实现,程序员多采用这种方式与内核交互,这些API通过系统调用来实现 系统命令 系统管理员采用系统命令与内核交互,是一个可执行文件,通过系统API及系统调用来实现 外壳程序 一系列系统命令和SHELL脚本共同组合成的程序。,C库的文件操作,文件系统调用,open系统调用 read系统调用 write系统调用 create系统调用 close系统调用 mkdir系统调用 ,文件描述符fd,每个进程PCB结构中有文件描述符指针,指向的文件描述符表,记录每个进程打开的文件列表 系统内核不允许应用程序访问进程的文件描述符表,只返回这些结构的索引即文件描述符ID()给应用程

4、序 Linux系统中,应用程序通过这些文件描述符来实现让内核对文件的访问 每个进程能够访问的文件描述符是有限制的,通过#ulimit n可以查看,特殊文件描述符号,标准输入STDIN_FILENO 标准输出STDOUT_FILENO 标准错误STDERR_FILENO,每个进程被加载后,默认打开0,1,2这三个文件描述符,open系统调用2-1,有几种方法可以获得允许访问文件的文件描述符。最常用的是使用open()(打开)系统调用 函数原型 int open(const char *path, int flags); 参数 path :文件的名称,可以包含(绝对和相对)路径 flags:文件打

5、开模式 返回值 打开成功,返回文件描述符; 打开失败,返回1,open系统调用2-2,函数原型 int open(const char *path, int flags,mode_t mode); 参数 path :文件的名称,可以包含(绝对和相对)路径 flags:文件打开模式 mode: 用来规定对该文件的所有者,文件的用户组及系统中其他用户的访问权限,则文件权限为:mode outfd = open(“my); if(outfd=-1) perror(“fail to open filen”); exit(-1); else perror(“success to open filen”)

6、; close(outfd); /关闭文件描述符 ,关闭文件close,将进程中fd对应的文件描述表结构释放 函数原型:int close(int fd); 函数参数: fd :要关闭的文件的文件描述符 返回值 如果出现错误,返回-1 调用成功返回0,read系统调用,一旦有了与一个打开文件描述相连的文件描述符,只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节 函数原型: int read(int fd, void *buf, size_t nbytes); 参数 fd :想要读的文件的文件描述符 buf: 指向内存块的指针,从文件中读取来

7、的字节放到这个内存块中 nbytes: 从该文件复制到buf中的字节个数 返回值 如果出现错误,返回-1 返回从该文件复制到规定的缓冲区中的字节数,文件结束,返回0否则,write系统调用,用write()系统调用将数据写到一个文件中 函数原型:int write(int fd,void *buf,size_t nbytes); 函数参数: fd :要写入的文件的文件描述符 buf: 指向内存块的指针,从这个内存块中读取数据写入 到文件中 nbytes: 要写入文件的字节个数 返回值 如果出现错误,返回-1 如果写入成功,则返回写入到文件中的字节个数,write()示例,#include #i

8、nclude #include void main() int outfd = 0, r_size = 0; char buf = “Hello world!”; outfd = open(“first”,O_WONLY | O_TRUNC | O_CREAT,S_IRWXU); if(outfd0) r_size = write(outfd,buf,sizeof(buf); if(r_size0) printf(“write data to ”); close(outfd); ,close系统调用,为了重新利用文件描述符,用close()系统调用释放打开的文件描述符 函数原型:int clo

9、se(int fd); 函数参数: fd :要关闭的文件的文件描述符 返回值 如果出现错误,返回-1 调用成功返回0,文件的随机读写,到目前为止的所有文件访问都是顺序访问。这是因为所有的读和写都从当前文件的偏移位置开始,然后文件偏移值自动地增加到刚好超出读或写结束时的位置,使它为下一次访问作好准备。 有个文件偏移这样的机制,在Linux系统中,随机访问就变得很简单,你所需做的只是将当前文件移值改变到有关的位置,它将迫使一次read()或write()发生在这一位置。(除非文件被O_APPEND打开,在这种情况下,任何write调用仍将发生在文件结束处),lseek系统调用 2-1,功能说明:通

10、过指定相对于开始位置、当前位置或末尾位置的字节数来重定位 curp,这取决于 lseek() 函数中指定的位置 原型:,off_t lseek (int fd, off_t offset, int base);,需设置的文件标识符,偏移量,搜索的起始位置,返回值:返回新的文件偏移值,lseek系统调用 2-2,base 表示搜索的起始位置,有以下几个值:(这些值定义在),chmod和fchmod系统调用,功能说明:用来改变给定路径名pathname的文件的权限位 原型:,int chmod (char *pathname, mode_t mode);,文件的路径名,权限位,返回值:调用成功返回

11、0,失败返回-1,int fchmod (int fd, mode_t mode);,文件描述符,权限位,chown和fchown系统调用,功能说明:用来改变文件所有者的识别号(owner id)或者它的用户组识别号(group ID) 原型:,int chown (char *pathname, uid_t owner,gid_t group);,文件的路径名,所有者识别号,返回值:调用成功返回0,失败返回-1,int fchown (int fd, uid_t owner,gid_t group);,文件描述符,用户组识别号,所有者识别号,用户组识别号,mkdir系统调用,功能说明:用来创

12、建一个称为pathname的新目录,它的权限位设置为mode 原型:,int mkdir(char *pathname,mode_t mode);,返回值:调用成功返回0,失败返回-1,文件的路径名,权限位,rmdir系统调用,功能说明:删除一个空目录 原型:,int rmdir(char *pathname);,返回值:调用成功返回0,失败返回-1,文件的路径名,目录访问 3-1,功能说明:打开一个目录 原型:,DIR* opendir(char *pathname);,返回值: 打开成功,返回一个目录指针 打开失败,则返回0,文件的路径名,目录访问 3-2,功能说明:访问指定目录中下一个连

13、接的细节 原型:,struct dirent* readdir(DIR *dirptr);,返回值: 返回一个指向dirent结构的指针,它包含指定目录中下一个连接的细节; 没有更多连接时,返回NULL,目录指针,目录信息结构体,struct dirent long d_ino; /* 目录i结点编号 */ off_t d_off; /* 目录文件开关至此目录进入点的位移 */ unsigned short d_reclen; /* d_name的长度 */ char d_name NAME_MAX+1; /* 以NULL结尾的文件名 */ 如果调用opendir打开某个目录之后,第一次调用r

14、eaddir函数,则返回的是该目录下第一个文件的信息,第二次调用readdir函数返回该目录下第二个文件的信息,依此类推。如果该目录下已经没有文件信息可供读取,则返回NULL。,目录访问 3-3,功能说明:关闭一个已经打开的目录 原型:,int closedir (DIR *dirptr);,返回值:调用成功返回0,失败返回-1,目录指针,目录操作示例,#include #include #include #include int my_read_dir(const char *path) DIR * dir; struct dirent *ptr; if( dir = opendir(pat

15、h) = NULL ) return -1; while( ptr = readdir(dir) != NULL ) printf(: %sn,ptr-d_name); closedir(dir); return 0; int main() if(my_read_dir(argv1) 0 ) exit(1); return 0; ,文件记录锁,什么是文件锁:当有多个进程同时对某一文件进行操作时,就有可能发生数据的不同步,从而引起错误,该文件的最后状态取决于写该文件的最后一个程序。 Linux中文件记录锁可以对文件某一区域进行文件记录锁的控制。它是通过fcntl函数来实现的。,fcntl函数,功

16、能说明:管理文件记录锁的操作 原型:,#include #include int fcntl (int fd,int cmd,struct flck *lock);,参数:fd:文件描述符; cmd:功能符号; (F_SETLK用来设置或释放锁; F_GETLK用来获得锁信息;) lock:存储锁信息的结构体指针;,返回值:调用成功返回0,失败返回-1,锁信息结构体,struct flock short l_type; /* 锁的类型 */ short l_whence; /* 偏移量的起始位置: */ off_t l_start; /* 从l_whence的偏移量 */ off_t l_len; /* 从l_start开始的字节数 */ pid_t l_pid; /* 锁所属进程ID(一般不用) */ l_type有F_RDLCK读锁、F_WRLCK写

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 商业/管理/HR > 管理学资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号