408操作系统知识-----文件系统基本操作

一.文件基本操作

二.文件基本操作及其对应的系统调用介绍

2.1.OS的管理框架

文件存在于磁盘(硬件设备)上,我们通过C/C++读取到文件,并不是我们想象中的直接读

问:能否直接操作磁盘读取文件吗??

答:不可以!如果经由C/C++直接操作,可能会擅自修改磁盘中的其他内容

       操作系统不相信任何人

2.2. C/C++读取文件的过程

C语言提供的 fopen函数,C++提供的 ofstream,都属于上层接口

open函数,属于系统接口,上层接口会去 调用系统接口 进入OS

我们这里仅关注 上层接口的调用 以及 系统接口的调用

2.2. 上层接口的调用

2.2.1.打开文件的功能实现,以open()和fopen()函数的调用为例

系统接口是open函数,首先看看调用系统接口需要哪些参数:

第一个参数:需要读取的文件所在路径

第二个参数:标志位(以读/写的方式打开文件)

第三个参数:权限设置

参数说明:

   这里主要说明第二个和第三个参数

第二个参数是标志位,告诉open函数是要以读还是以写的方式打开文件,第二个参数必须包含O_RDONLY, O_WRONLY, 以及 O_RDWR  中的一个。

O_WRONLY:以写的方式打开文件
O_RDONLY:以读的方式打开文件
O_WRONLY:以读写的方式打开文件
在此基础上可以附加其他参数

O_CREAT:当文件不存在时,创建文件
O_APPEND:在文件末尾追加

   第三个参数是文件权限设置

Linux中每一个文件被创建出来都自带权限,分别表示用户权限、组权限、其他权限

第三个参数就是设置权限,示例给的 0644 是 8进制 (6 表示011,对应上面的 -rw)

(3)返回值:文件描述符

打开/创建不同的文件,文件描述符不同,设置对应的文件描述符方便OS管理各种文件

下面打开了五个不同的文件,所以会被分配五个不同的文件描述符

补充:

文件描述符从3开始,是因为C在运行程序之前,会自动打开三个输入输出流,分别是stdin、stdout、stderr

        stdin:标准输入,对应的外设是键盘            fd:0

        stdout:标准输出,对应的外设是显示器      fd:1

        stderr:标准错误,对应的外设是显示器       fd:2

函数原型

FILE *fopen(const char *filename, const char *mode);

参数

  • filename-- 这是 C 字符串,包含了要打开的文件名称。

  • mode-- 这是 C 字符串,包含了文件访问模式。

功能

   使用给定的模式mode打开filename所指向的文件。

返回值

  文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回 NULL,并把错误代码存在error中。

  一般而言,打开文件后会做一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在 fopen() 后作错误判断及处理。

参数说明

   参数mode字符串包含了文件访问模式,欲打开的文件路径及文件名,参数 mode 字符串则代表着流形态。

  mode 有下列几种形态字符串

字符串

说明

r

以只读方式打开文件,该文件必须存在。

r+

以读/写方式打开文件,该文件必须存在。

rb+

以读/写方式打开一个二进制文件,只允许读/写数据。

rt+

以读/写方式打开一个文本文件,允许读和写。

w

打开只写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。

w+

打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。

a

以附加的方式打开只写文件。若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF 符保留)。

a+

以附加方式打开可读/写的文件。若文件不存在,则会创建该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF符不保留)。

wb

以只写方式打开或新建一个二进制文件,只允许写数据。

wb+

以读/写方式打开或新建一个二进制文件,允许读和写。

wt+

以读/写方式打开或新建一个文本文件,允许读和写。

at+

以读/写方式打开一个文本文件,允许读或在文本末追加数据。

ab+

以读/写方式打开一个二进制文件,允许读或在文件末追加数据。

fopen()系统调用背后的过程如下:

2.2.2.读文件功能的实现,以read()调用为例

   系统调用提供给应用程序的 调用请求接口,调用请求中执行了 软中断的指令,应用程序使用调用请求后, 处理器会产生一个中断,中断服务得到执行,中断服务根据 调用号执行特定的功能实现函数。

注:图很重要,要多对照看

    系统调用是昂贵的,因为这个过程,涉及到用户态到内核态的切换,而这个切换的过程是通过中断实现的,从用户态切换到内核态需要保护现场,从内核态到用户态时需要恢复现场,也就是上下文切换了,所以一次系统调用的开销,还是蛮大的。

  系统调用是操作和理解 操作系统内核的关键切入点,系统调用只是入口,真正的工作都是内核完成。内核中会有很多机制来完成这些工作,比如内核的驱动模块、内核的中断系统等,这些都是做内核开发时会经常设计的模块。

read系统调用的原型:

#include <unistd.h>    
ssize_t read(int fd, void *buf, size_t count);  

read系统调用,是从与文件描述符flides相关联的文件中读取前nbytes字节的内容,并且写入到数据区buf中。read系统调用返回的是实际读入的字节数 

参数

   fd是文件描述符,count是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移。注意这个读写位置和使用C标准I/O库时的读写位置有可能不同,这个读写位置是记在内核中的,而使用C标准I/O库时的读写位置是用户空间I/O缓冲区中的位置。比如用fgetc读一个字节,fgetc有可能从内核中预读1024个字节到I/O缓冲区中,再返回第一个字节,这时该文件在内核中记录的读写位置是1024,而在FILE结构体中记录的读写位置是1。注意返回值类型是ssize_t,表示有符号的size_t,这样既可以返回正的字节数、0(表示到达文件末尾)也可以返回负值-1(表示出错)。

返回值

    read函数返回时,成功则返回读取的字节数,出错返回-1并设置errno返回值,说明了buf中前多少个字节是刚读上来的。有些情况下,实际读到的字节数(返回值)会小于请求读的字节数count,例如:读常规文件时,在读到count个字节之前已到达文件末尾。例如,距文件末尾还有30个字节而请求读100个字节,则read返回30,下次read将返回0。

2.2.3.写文件功能的实现,以write()调用为例

头文件#include <unistd.h>

三个参数

函数说明:write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。

返回值:如果顺利write()会返回实际写入的字节数(len)。当有错误发生时则返回-1,错误代码存入errno中。

//  write(int  fd,  const  void  *buf, size_t count);

第一个参数 文件描述符fd

第二个参数 无类型的指针buf,可以存放要写的内容

第三个参数 写多少字节数

2.2.4.关闭文件功能的实现,以close()调用为例

终止文件描述符flides与其对应的文件间的联系,文件描述符被释放,可重新使用。

#include <unistd.h>

int close(int flides);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
操作系统课程设计报告 题 目: 文件系统的模拟设计 一、设计目的 本课程设计是学习完"操作系统原理"课程后进行的一次全面的综合训练,通过课程 设计,更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的 理解,加强学生的动手能力。 二、设计内容 (1)概述 为Linux系统设计一个简单的二级文件系统。要求做到以下几点: 1.可以实现下列几条命令: login 用户登录 dir 列目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件 cd 进出目录 2.列目录时要列出文件名,物理地址,保护码和文件长度 3.源文件可以进行读写保护 (2)设计原理和系统总体功能框架图 1、在内存中开辟一个虚拟磁盘空间作为文件存储器,在其上实现一个多用户多目录 的文件系统。 2、文件物理结构可采用显式链接或其他方法。 3、磁盘空闲空间的管理可选择位示图或其他方法。如果采用位示图来管理文件存储 空间,并采用显式链接分配方式,则可以将位示图合并到FAT中。 4、文件目录结构采用多用户多级目录结构,每个目录项包含文件名、物理地址、长 度等信息,还可以通过目录项实现对文件的读和写的保护。 5、对文件或目录的操作采用windows系统的API函数来实现。 6、设计一个较实用的用户界面,方便用户使用。要求提供以下相关文件操作:用户 登录、创建目录、删除目录、创建文件、删除文件、读文件、写文件、复制文件、移动 文件、返回根目录、退出。 功能结构图如图1.0所示: (3)详细设计及少数重要编码的说明 这次课程设计中,我负责4个板块,分别是显示列表函数和目录、创建函数文件创 建函数、打开文件函数和关闭文件系统函数。 1. 显示列表函数和目录 流程图如图1.1所示 2. 文件创建函数 算法:查找当前目录下是否有同名文件,是则退出,否则让用户输入文本文件内容 ,以'###'结束。申请inode空间(ialloc函数),申请硬盘block空间(balloc函数), 申请失败则结束。将文件内容写入inode空间和block空间。修改当前目录的结构,修改 inode位图,block位图,写入模拟硬盘。详细过程如流程图1.2所示: 、打开文件函数 对文件进行关闭操作,若此时文件不存在或处于读状态或写状态,则返回关闭失败信 息;若此时文件处于空闲状态,则调用Close函数进行关闭操作。流程图如图1.3所示 : 、关闭文件系统函数 对文件进行打开操作,若此时文件不存在或已处于打开状态或读状态或写状态,则返回 打开失败信息;若此时文件处于空闲状态,则调用Open函数进行打开操作。流程图如图 1.4所示: (4)运行结果分析 程序结果如图1.5-1.7所示 图1.5 图1.6 图1.7 (5)设计小结 操作系统课程设计是本课程重要的实践教学环节。课程设计的目的,一方面使学生 更透彻地理解操作系统的基本概念和原理,使之由抽象到具体;另一方面,通过课程设 计加强学生的实验手段与实践技能,培养学生独立分析问题、解决问题、应用知识的能 力和创新精神。与本课程的实验教学相比,课程设计独立设课,具有更多的学时,给学 生更多自行设计、自主实验的机,充分放手让学生真正培养学生的实践动手能力,全 面提高学生的综合素质。 对于本次操作系统课程设,由于Linux比较陌生,刚起步阶段花了很大时间去查阅各 种资料。当完成设计时,感觉掌握了以前学到的知识,并且还对操作系统应用有了更深 入的认识。对二级文件系统也有了很好的了解,熟练C语言布局的使用,如何解决实现里 面功能的各种问题。 (6)参考文献 [1]计算机操作系统(第3版),汤小丹,西安电子科技大学出版社,2007年7月 [2]C语言程序设计,孟庆昌,人民邮电出版社,2006年4月 [3]计算机操作系统教程(第3版)习题解答与实验指导,张尧学,清华大学出版社, 2006年11月 (7)附源代码 12、显示列表函数dir( )和目录创建函数mkdir( )等(文件名dir.c) #include "stdio.h" #include "string.h" #include "filesys.h" _dir( ) /*dir*/ { unsigned int di_mode; int i,j,one; struct inode *temp_inode; printf("\nCURRENT DIRECTORY:\n"); for(i=0;i<DIRNUM;i++) {if(!(strcmp(dir.direct[i].d_name,""))&&(dir.direct[i].d_ino==0)) { dir.size = i;break; }} for(i=0;i<dir

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值