精华内容
下载资源
问答
  • 操作系统学习笔记:文件系统接口

    千次阅读 2015-07-21 22:46:25
    名称、标识符(文件系统内文件的唯一标签)、类型、位置(指向设备和设备上文件位置的指针)、大小、保护、时间2、文件操作 1)创建。有两个必要步骤:第一必须在文件系统中为文件找到空间,第二在目录中为新文件

    计算机设备之间差异很大,所以操作系统需要提供一组功能以便于应用程序控制这些设备。操作系统的IO子系统的重要目的之一是为系统其它部分提供最简单的接口。文件接口是接口之一。

    一、文件概念
    1、文件属性
    名称、标识符(文件系统内文件的唯一标签)、类型、位置(指向设备和设备上文件位置的指针)、大小、保护、时间

    2、文件操作
    1)创建。有两个必要步骤:第一必须在文件系统中为文件找到空间,第二在目录中为新文件创建一个条目

    2)写
    系统要为该文件维护一个写位置的指针。每当有写操作必须更新写指针。

    3)读
    为了读文件,使用一个系统调用,并指明文件名称和要读入文件块的内存位置。系统为该文件维护一个读位置指针。读和写使用同一指针。

    4)文件内重定位
    设置当前文件位置指针(读写指针)为给定值。不需要真正的IO,又称为文件寻址。

    5)删除
    6)截断

    以上是文件的6个基本操作。

    为提高性能,绝大多数OS要求使用文件的时候,显式打开。OS会维护一个全局的打开文件表,以满足各种文件操作需要用到的搜索、定位需求。每个打开文件还有一个文件计数器,以记录多少进程打开了该文件。总的来说,打开文件有:
    文件指针,文件打开计数器,文件磁盘位置,访问权限

    3、文件类型
    实现文件类型的常用技术是在文件名称内包含类型,比如采用名称 + 扩展名的方式,后者像UNIX,采用幻数(magic number),保存在文件的开始部分,但这些都不是必须的。真正确定文件类型,或是否要使用该文件,由应用程序开发者决定。文件扩展名并非由操作系统所支持,只用于给操作它们的应用程序以提示。

    不过,像Mac OS X,每个文件都有类型,创建时强制其创建者为相应的应用程序。

    操作系统是否支持文件类型是一件很纠结的事情。支持的文件类型太少,会很不方便;太多又会让操作系统过大。

    4、文件结构
    磁盘系统通常具有明确的块大小,而逻辑记录则长度可变。常用解决办法是先将若干逻辑记录打包,再放入物理记录。文件可当做一系列块的组合。文件最后一块通常会有浪费,块越大,内部碎片就越大。

    二、访问方法
    1、顺序访问(磁带模型)
    读操作自动前移文件指针,写操作在文件尾部增加内容,文件指针移到新增数据后。当然指针也可重置到开始位置,或者向前向后跳过N个记录。
    顺序访问适用于顺序访问设备,也适用于随机访问设备。

    2、直接访问(磁盘模型)
    文件由固定长度的逻辑记录组成,按任意顺序进行快速读和写。
    操作之时,块号作为参数传入,可以迅速定位。通常,这个由用户向操作系统提供的块号是相对块号,相对于文件开始的索引。文件系统由这个块号做一定的运算,比如哈希运算,得到绝对块号。
    对支持直接访问的文件,当然也很容易实现顺序访问。

    3、其他访问方式
    其他访问方式可建立在直接访问方式之上,这些访问通常涉及创建文件索引。索引包括各块的指针。查找文件中的记录,首先搜索索引,再根据指针直接访问文件。
    对于大文件,索引会分级。

    三、目录结构
    同一个操作系统可以存在若干个文件系统。这好理解,像我们的电脑中,一个盘是FAT32,另一个盘可能是NTFS。
    1、存储结构

    典型的文件系统组成

    卷:硬盘上的存储区域。驱动器使用一种文件系统(如 FAT 或 NTFS)格式化卷,并给它指派一个驱动器号。单击“Windows 资源管理器”或“我的电脑”中相应的图标可以查看驱动器的内容。一个硬盘包括好多卷,一卷也可以跨越许多磁盘

    2、目录概述
    目录可看做符号表,能将文件名称转换成目录条目。目录有多种操作:
    搜索文件、创建文件、删除文件、遍历目录、重命名文件、跟踪文件系统。所谓跟踪文件是指掌握整个文件系统的细节,有哪些目录和文件,使用情况如何,等等。

    3、单层结构目录
    所有文件都在同一目录中,济济一堂,热闹。便于理解和支持。但多用户时,会有严格限制。比如文件名唯一问题。

    4、双层结构目录
    每个用户都有自己的用户文件目录。每个用户的文件目录结构都一样。当用户引用特定文件时,只需搜索他自己的目录。再也不用担心自己的文件名与其他用户的重名了。

    这种结构,如果用户完全独立是优点,但如果之间需要合作交互就是缺点。这种情况下,文件路径需要带上用户名(感觉类似数据库里面的schema)。文件系统中的不同分区可看成是不同的用户。

    有一个特例是系统文件。系统文件作为公用,如果只能在用户自己文件目录内搜索的话,那么每个用户目录都应该有一份,太浪费。解决办法是定义一个特殊用户目录,所有系统文件置于其中。当需要搜索时,先搜用户文件夹,找不到就搜这个特殊目录。

    5、树状结构目录
    二层结构扩展而来。允许用户创建自己的子目录。

    6、无环图目录
    树状结构目录扩展。允许共享目录和文件,即同一文件可分属多个不同的目录。
    UNIX中,共享目录或文件处理为链接。

    7.通用图目录
    无环图目录有时容易出现环,比如链接中,出现了自我引用的情况。存在环可能会导致遍历目录时死循环。应避免出现环,或者出现之后要消除,比如增加垃圾回收,消除哪些没有引用或自引用的链接。或者改变遍历算法,遍历目录时避开链接。

    四、文件系统安装
    文件系统要正确使用,必须安装

    五、文件共享
    1、多用户

    2、远程文件系统
    NFS:网络文件系统
    DFS:分布式文件系统
    1)客户机-服务器模型

    2)分布式信息系统
    为了便于管理客户机-服务器服务,提供用于远程计算所需信息的统一访问

    3)故障模式
    远程文件系统很容易出现各种故障,比如掉线等。当故障出现时,客户机系统并不将此作为本地文件系统故障那样进行处理,但会终止对故障服务器的所有操作,或者等候直至服务器再次可用。这种故障语义由远程文件系统协议所定义和实现。通常,终止操作代价较大,绝大多数分布式文件系统在故障出现时,选择等候。

    那么故障恢复时,客户机和服务器之间可能需要一定的状态信息。NFS采用了一种简单的方法实现了无状态的DFS,但它不够安全。

    3、一致性语义
    多用户操作情况下,如何保持文件一致性。
    1)UNIX语义
    用户的写操作,可以被其他所见
    允许用户共享文件指针位置,移动文件指针会影响其他用户

    采用UNIX语义,一个文件与单个物理映射关联,互斥访问。

    2)会话语义
    用户写操作不能立即被打开同一文件的其他用户所见
    文件关闭后,修改只能被新打开的会话所见,已经打开的用户看不到

    采用这种语义,一个文件可以对多个物理映射进行关联,并发性很好。

    3)不可修改共享文件语义
    既然是共享文件,就不能修改,只读。

    在分布式系统中实现这种语义最简单。

    六、保护
    文件的保护包括可靠性保护和防止非法访问。可靠性通常由文件备份提供;这里说的保护是指防止非法访问。
    1、访问类型
    通过限制可进行的文件访问类型,比如说:
    读、写、执行、添加、删除、列表清单

    2、访问控制
    文件对应访问控制列表,而此列表与所有者、组、其他成员组合使用。

    3、其他保护方式
    文件加密码。

    展开全文
  • Linux 文件操作系统调用接口

    千次阅读 2016-08-15 14:19:06
    它不仅仅是对普通文件操作接口,也是设备通信、进程间通信、网络通信的重要编程接口。因 此文件操作的相关调用也是Linux内核提供的最重要的编程接口。    本节将重点叙述如下几个常用的文件操作系统调用。 ...

    文件操作的系统调用接口:
     文件是Linux系统中的重要概念。它不仅仅是对普通文件的操作接口,也是设备通信、进程间通信、网络通信的重要编程接口。因

    此文件操作的相关调用也是Linux内核提供的最重要的编程接口。
     
     本节将重点叙述如下几个常用的文件操作系统调用。
     open:打开文件。
     read:从已打开的文件中读取数据。
     write:向已打开的文件中写入数据。
     close:关闭已打开的文件。
     ioctl:向文件传递控制信息或发出控制命令。
     
     对文件的操作工程一般是这样的:先打开文件,内核对打开的文件进行管理,打开成功后应用程序将获得文件描述符;然后应用程

    序使用文件描述符对文件进行读写操作;当全部操作完毕后,应用程序需要将文件关闭以释放用于管理打开文件的内存。
     文件描述符是一个取值从0开始的整数。内核默认一个进程同时打开的文件数有一个上限,也就是文件描述符取值的上限,一般是

    1024。
     每个进程在启动后就默认有三个打开的文件描述符0,1,2,如果启动程序时没有进行重定向,则文件描述符0关联到标准输入,1关

    联到标准输出,2关联到标准错误输出。在C库函数中可以使用以下几个宏来表示这几个文件描述符:
     #define STDIN_FILENO   0
     #define STDOUT_FILENO  1
     #define STDERR_FILENO  2


    打开文件:
     在访问文件之前,首先应打开文件。可以使用open或creat函数来打开文件,它们的接口头文件及函数原型如下:
     #include <sys/types.h>
     #include <sys/stat.h>
     #include <fcntl.h>
     int open(const char *pathname, int flags);
     int open(const char *pathname, int flags, mode_t mode);
     int creat(const char *pathname, mode_t mode);

     其各个参数及返回值的含义解释如下.
     ◆ pathname:要打开的文件名称。
     ◆ flags:标志位,指定打开文件的操作方式及打开时的一些行为。
     ◆ mode: 用于指定新文件的权限标志位。
     ◆ 返回值:操作成功则返回文件描述符,否则返回-1并设置标量errno的值。

     flags参数有以下几个基本的取值。
     ◆ O_RDONLY:以只读方式打开文件。
     ◆ O_WRONLY:以只写方式打开文件。
     ◆ O_RDWR:以读写方式打开文件。

     这几个标志位指定打开文件的操作方式,它们是互斥的,不能同时使用,但可以与下述标志用按位或的方式组合起来使用。
     ◆ O_CREAT:如果被打开的文件不存在,则自动创建这个文件。
     ◆ O_EXCL:如果O_CREAT标志已经使用,那么当由pathname参数指定的文件已经存在时open函数返回失败。如果pathname给出的是 

      一个符号链接,无论它指向的文件是否存在,对open函数的调用都会返回失败。
     ◆ O_NOCITY:如果被打开的文件是一个终端设备文件(如/dev/tty),它不会成为这个进程的控制终端。
     ◆ O_TRUNC:如果被打开的文件存在并且是以可写的方式打开的,则清空文件原有内容。
     ◆ O_APPEND:新写入的内容将被附加在文件原来的内容之后,即打开后文件的读写位置被置于文件尾。
     ◆ O_NONBLOCK:被打开的文件将以非阻塞的方式进行操作。
     ◆ O_NDELAY:同O_NONBLOCK。
     ◆ O_SYNC:被打开的文件将以同步I/O的方式进行操作,即任何写操作都会先被同步到硬件设备上。同步完成后,对写函数的调用 

      才返回。
     ◆ O_NOFOLLOW:如果pathname是一个符号链接,则对open函数的调用将返回失败。
     ◆ O_DIRECTORY:如果pathname不是目录,则对open函数的调用将返回失败。

     需要注意的是,open函数有两个原型,其中一个多出了个参数mode,它用于指定创建的新文件的访问权限。如果打开时使用了

    O_CREAT标志创建新文件,则一般都要给出mode参数,它的一些常用取值如表所示,这些值可以用按位或的方式组合使用。新文件的所属用

    户和所属组则是创建它的进程的所属用户和所属组。
     权限标志定义  对应的八进制形式  含义
     S_IRWXU   00700    文件所属用户有读写和执行权限
     S_IRUSR(S_IREAD) 00400    文件所属用户有读权限
     S_IWUSR(S_IWRITE) 00200    文件所属用户有写权限
     S_IXUSR(S_IEXEC) 00100    文件所属用户有执行权限
     S_IRWXG   00070    组内用户有读写和执行权限
     S_IRGRP   00040    组内用户有读权限
     S_IWGRP   00020    组内用户有写权限
     S_IXGRP   00010    组内用户有执行权限
     S_IRWXO   00007    其他用户有读写和执行权限
     S_IROTH   00004    其他用户有读权限
     S_IWOTH   00002    其他用户有写权限
     S_IXOTH   00001    其他用户有执行权限

     鉴于在调用open函数时,O_WRONLY,O_CREAT,O_TRUNC三个标志位经常组合使用,因此由一个专门的函数creat来实现。如下:
     creat(pathname, mode); 
     实际上等价于:
     open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);
     
     这两个函数在打开文件成功时将返回一个文件描述符,可用于随后的read/write或其他对文件的操作使用。两个不同的进程打开同

    一个文件是允许的,但它们得到的文件描述符一般是不同的。如果它们都对文件进行写操作,就会出现数据不一致的情况,也就是最后写入

    的可能覆盖先前其他进程写入的内容,这就涉及到进程间数据共享和同步的概念了。
     如果打开操作失败,这两个函数会返回-1,并将errno变量设置为一个合适的错误值。

    从文件读取数据:
     文件打开后就可以进行读写操作了。读操作的接口头文件及函数原型如下:
     #include <unistd.h>
     ssize_t read(int fd, void *buf, size_t count);

     其各个参数及返回值的含义解释如下:
     ◆ fd:要读取的文件描述符。
     ◆ buf:指向读取到的数据要放入的缓冲区。(buf指向的内存空间必须事先分配好)
     ◆ count:要读取的字节数(缓冲区大小)。
     ◆ 返回值:读取到的字节数,失败返回-1,并设置标量errno的值。

     这里的size_t型实际上就是无符号整型,而ssize_t型就是有符号整型。
     这个函数将从fd代表的文件的当前读写位置读取不超过count个字节到buf指向的内存中,并返回读到的字节数。

     对于普通文件来说,读操作完成后,文件的读写位置会向后移动,移动的长度就是读取的字节数,下一次读操作将从新的读写位置

    开始。
     read函数的返回值小于指定的count是可能的,并不是错误。出现这种情况有各种原因,比如,文件本身可供读取的字节数比count

    小或者read系统调用被信号打断等。read系统调用看似简单,但实际上对于各种可能情况的处理是比较复杂的,因为I/O操作有很多异常情

    况要考虑到。下面列出了read系统调用中可能遇到的情况及其处理方法。
     ◆ 调用返回值等于count,读取的数据存放在buf指向的内存中,结果与预期一致。
     ◆ 调用返回一个大于0小于count的值,读取的字节数存放在buf指向的内存中。出现这种情况可能是一个信号打断了读取过程,或 

      在读取中发生了一个错误,或读取的有效字节数大于0但不足count个,或在读入count个字节前文件已经结束。如果读取 

      的过程被信号打断则可以再次进行读取。
     ◆ 调用返回0,说明文件已结束,没有可以读入的数据。
     ◆ 调用阻塞,说明没有可读的数据,这种情况下如果以非阻塞方式操作文件,那么会立即返回错误。
     ◆ 调用返回-1,并且errno变量被设置为EINTR,表示在读入有效字节前收到一个信号,这种情况可以重新进行读操作。
     ◆ 调用返回-1,并且errno变量被设置为EAGAIN,这说明是在非阻塞方式下读文件,并且没有可读的数据。
     ◆ 调用返回-1,并且errno变量被设置为非EINTR或EAGAIN的值,表示有其他类型的错误发生,必须根据具体情况进行处理。

     由于有各种异常情况的存在,为了从文件中可靠的读取指定的字节数,就必须对这些情况进行处理,必要时需重新进行读操作。这

    对于设备文件、管道或socket来说尤其有意义。例如,用下面的代码能够可靠的从文件中读取指定的字节数(假设文件是以阻塞的方式进行

    操作的):
     ssize_t ret;
     while(len != 0 && (ret = read(fd,buf,len)) != 0)
     {
      if(ret == -1)
      {
       if(errno == EINTR) continue;
       perror("read");
       break; 
      }
      len -= ret;
      buf += ret; 
     }
     这里把操作放在循环中,当一次读操作没有得到len个字节时,将调整len和buf的值继续进行操作。如果读操作返回-1,说明有错

    误发生,这时如果错误码是EINTR,说明只是被信号打断,可以继续读,其他情况则被认为是严重的错误,不能再继续读。
     以上是以阻塞方式读文件的例子,这时,如果文件是一个设备文件并且设备没有可读的数据,进程将进入睡眠状态不再继续执行,

    或者说阻塞在read系统调用处,直到设备有了可读的数据才会被唤醒继续执行。很多时候我们需要进程能够立刻返回以处理其他的事物,那

    么就需要采用非阻塞的方式来操作文件,举例如下:
     ssize_t nr;
     start:
     nr = read(fd, buf, len);
     if(nr == -1)
     {
      if(errno == EINTR)  goto start;
      if(errno == EAGAIN)  
      {
       /*处理其他事物,在恰当时再调用read*/
      }
      else
      {
       /*有错误发生,处理错误*/
      }
     } 
     可以看到,在采用非阻塞的方式读文件时,如果读操作返回-1,我们必须检查错误码是否为EINTR或EAGAIN,如果是EINTR,可以再

    次进行读操作,而如果是EAGAIN,表示要读取的(设备)文件现在没有可供读取的数据,因此进程可以继续处理其他事物,而后在恰当的时

    机再来读取这个文件。
      
    写数据到文件:
     向打开文件中写入数据的接口头文件及函数原型如下:
     #include <unistd.h>
     ssize_t write(int fd, const void *buf, size_t count);

     其各个参数及返回值的含义解释如下。
     ◆ fd:要写入的文件的描述符。
     ◆ buf:指向要写入的数据所存放的缓冲区。
     ◆ count:要写入的字节数。
     ◆ 返回值:实际写入的字节数,失败则返回-1,并设置变量errno的值。

     这个函数会从fd所代表的文件当前读写位置开始,把buf指向的内存中最多count个字节写入文件。写入成功则返回写入的字节数,

    并更新文件的读写位置。
     write系统调用返回大于0而小于count的值是合法的,并不表示有错误发生。
     ◆ 调用返回值等于count,说明数据全部写入成功。
     ◆ 调用返回一个大于0小于count的值,说明部分数据没有写入。这可能是因为写入过程被信号打断,或者底层的设备暂时没有足 

      够的空间存放写入的数据。
     ◆ 调用阻塞,说明暂时不能写入数据,这种情况下如果以非阻塞方式操作文件,那么会立即返回错误。
     ◆ 调用返回-1,并且errno变量被设置为EINTR,表示在写入一个有效字节前,收到一个信号,应用程序可以再次进行写操作。
     ◆ 调用返回-1,并且errno变量被设置为EAGAIN,说明是在非阻塞方式下写文件但文件暂时不能写入数据。
     ◆ 调用返回-1,并且errno变量被设置为EBADF,表示给定的文件描述符非法,或者文件不是以写方式打开。
     ◆ 调用返回-1,并且errno变量被设置为EFAULT,表示buf是无效的指针。
     ◆ 调用返回-1,并且errno变量被设置为EFBIG,表示写入的数据超过了最大的文件尺寸,或者超过了允许的文件读写位置。
     ◆ 调用返回-1,并且errno变量被设置为EPIPE,说明写入时发生了数据通道断层的错误,这种情况只在文件是管道或者是socket 

      的情况下发生。在这种情况下,进程还将收到一个SIGPIPE信号,信号的默认处理程序是使进程退出。
     ◆ 调用返回-1,并且errno变量被设置为ENOSPC,说明底层设备没有足够的空间。
     
     写文件举例如下:
     ssize_t ret;
     while(len != 0 && (ret = write(fd, buf, len)) != 0)
     {
      if(ret == -1)
      {
       if(errno == EINTR) continue;
       perror("write"); 
       break;
      } 
      len -= ret;
      buf += ret;
     }
     这里假定写操作是以阻塞的方式进行的。如果以非阻塞方式进行写操作,则当函数返回-1时,必须检测errno变量的值是否为

    EAGAIN,以决定能否再进行写操作。
     

    发送控制命令:
     在Linux系统上,那些不能被抽象为读和写的文件操作统一由ioctl操作代表。ioctl操作用于向文件发送控制命令,这些命令不能

    被视为是输入输出流的一部分,而只是影响文件的操作方式。对于设备文件来说,ioctl操作常用于修改设备的参数。
     ioctl系统调用的接口头文件及函数原型如下:
     #include <sys/ioctl.h>
     int ioctl(int fd, int request, ...);
     
     ◆ fd:要操作的文件描述符。
     ◆ request:代表要进行的操作,不同的(设备)文件有不同的定义。
     ◆ 可变参数:取决于request参数,通常是一个指向变量或结构体的指针。
     ◆ 返回值:成功返回0,有效ioctl操作返回其他非负值,错误返回-1。

     ioctl能够进行的操作根据fd所代表的文件的具体类型而变化,非常繁多。下面举一个例子,使用TIOCGWINSZ命令获得终端的窗口

    大小,如下:
     

    复制代码
    /*文件名:console_size.c*/
     /*说明:使用ioctl获得控制台窗口的大小*/
     #include <stdio.h>
     #include <stdlib.h>
     #include <unistd.h>
     #include <sys/ioctl.h>
     
     int main(void)
     {
                 struct winsize size;
                 /*判断标准输出是否为tty设备,防止输出被重定向的情况*/
                 if(!isatty(STDOUT_FILENO) < 0) return -1;
                 /*获得窗口大小*/
                if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) < 0)
               {
                        perror("ioctl TIOCGWINSZ error");
                        return -1; 
               }
               /*输出结果*/
               printf("rows is %d, columns is %d\n", size.ws_row, size.ws_col);
    
              return 0;
     }
    复制代码

     

     
    关闭文件:
     程序完成对文件的操作后,要使用close系统调用将文件关闭,其接口头文件与函数原型如下:
     #include <unistd.h>
     int close(int fd);
     
     fd是要关闭的文件的描述符,返回值在操作成功的情况下是0,否则是-1.

    展开全文
  • 操作系统总结之文件系统接口

    千次阅读 2011-05-15 16:16:00
    文件系统包含了文件和目录。目录用以组织文件,包含了文件的简要信息。放在外存。在计算机中有许多不同的介质,而计算机把这些抽象成一个统一的逻辑单元,再映射到物理设备。文件有很多不同的类型,比如:1.文本文件...

    文件在用户看来是再熟悉不过的名字了。因为能够创建文件,把一些数据放在文件中。
    文件系统包含了文件和目录。
    目录用以组织文件,包含了文件的简要信息。放在外存。
    在计算机中有许多不同的介质,而计算机把这些抽象成一个统一的逻辑单元,再映射到物理设备。
    文件有很多不同的类型,比如:
    1.文本文件:由行组成的文件。
    2.二进制文件。
    3.源文件。由子程序和函数构成。

    一个文件有自己的属性:
    1.文件名,identifier,类型,位置,大小,保护,时间。即最近访问时间,最近修改时间,文件创建时间。
    这些文件属性都放在目录中。

    文件有许多操作,比如创建,删除,重定位,读,写。
    创建文件需要找到一个空的空间,在目录中创建一个条目,指向文件。
    读:系统调用,控制读指针。
    写:系统调用,控制写指针。
    重定位:首先声明一点,读和写的指针是共用的,因此只需要把这个指针移动即可。
    删除:释放文件空间并在目录中删除条目。

    每次执行一个操作都要遍历目录,找到文件,但是这样速度很慢,因为目录在外存。
    我们要对一个文件进行操作必须要显式地打开文件。
    在操作系统中维护了一个open-file table,记录了打开的文件,以后每次操作,只需要索引这个表即可。
    但是对于多进程,可能同时打开一个文件,因此操作系统维护了两级的表:一个进程单独一个表,操作系统维护一个系统表。
    单个进程的表条目指向系统表。
    对于多进程访问一个文件时,需要在文件表中置一个计数器,等到计数器为0时再删除条目。
    当然对于多进程同时访问,可以用锁来解决同步问题。
    专用锁:类似写者锁。一个进程访问一个文件,其他进程就不能访问。
    共享锁:类似于读者锁。多进程可同时访问。

    文件类型:
    操作系统预先必须要声明支持哪些文件类型。
    Windows通过加扩展名来声明类型。
    Unix通过幻数在文件头部加声明类型。
    每个文件类型都有自己特有的结构,因此如果操作系统支持文件类型过多,就会出现操作系统过于庞大。
    磁盘的最小单元是块,因此一个块中可以放多个逻辑记录。一个文件由多个块组成。但是一个块可能会没放满,所以会出现内部碎片。

    访问文件信息的第一步必须将他所在的块读入内存。
    接下来就是不同的访问方法。
    1.顺序访问
    一条一条访问。
    2.直接访问
    因为文件的一条记录是固定长度的,因此可以利用公式快速计算出所要找的那个记录的位置。
    相对块号:相对于文件的块号。即文件的第一个块为0.

    对于目录,我们也要利用数据结构,这样就可以快速索引。
    一个磁盘可能有多个文件系统。一个卷有相关信息。记录大小,名称等。

    对于目录,我们如果要找到文件,必须要通过目录,如果create一个文件,就必须在目录中添加一个条目。
    为了更好更快地访问文件,我们对于目录进行一些构造。
    1.单层目录。
    只能一个用户,并且每个目录的名字必须唯一。
    2.双层目录。
    第一层是MFD。一个record是一个用户。
    一个用户对应一个单层目录。UFD。
    缺点:不能多用户共享或多目录共享文件。

    对于系统文件,我们需要定义一个特殊的用户目录。他包括所有系统文件,这个目录在其他目录都找不到的情况下会自动遍历。
    3.树状目录。
    禁止共享文件或目录。
    就是树状的目录结构,内部有子目录和文件。通过一位来表示是目录还是文件。
    对于删除目录,有两种解决方法:
    1.如果这个目录有子目录或文件,则不能删。
    2.Unix。删除目录的子目录和文件。

     

    4.无环图目录。
    允许共享。
    实现共享的方法:
    1.链接。一个指针指向一个文件。
    2.复制目录条目。像其他目录条目一样。但是要维护一致性。
    对于删除,也会出现问题。解决方案:
    1.删除链接时,则不变,删除文件条目,则链接无效。
    2.删除全部引用才删除。为每个文件建立一个引用计数器或文件引用表,当引用为空,则删除文件。

    MS-DOS采用树状目录结构。

     

    5.通用图目录。
    可以存在环,会无限遍历。

    解决方法:通过记录目录被访问次数来强制终止。

    删除文件时,由于存在环而等不到引用计数为0,因此通过垃圾收集解决引用技术问题。

    总结:为了避免过大开销,避免链接。

    文件系统在使用前必须要mount,安装时要指明安装位置即安装点。然后操作系统要验证文件系统安装的有效性。再是如果mount在一个目录下,原来在这个目录下的子目录的文件就不能使用了。必须要将unmount新的文件系统才行。在pintos中,我一开始把虚拟机和windows的共享数据空间在Desktop,发现原来的Desktop的东西打不开了。。。慌了我半天。。

    文件共享的三种实现方式:

    1.人工传输。

    2.远程登录。

    3.浏览器。

    对于文件共享,每个文件系统都有不同的语义,现在不只是多用户本地共享,也会有远程文件系统的共享。
    对于多用户的文件共享问题,我们需要明确每个用户的文件访问权限。
    拥有者需要有最高的权限。
    组需要有权限的子集。
    拥有者ID和组ID 保存在文件属性中。每次对文件进行操作都要比对。
    1.在unix中,对于一个用户进行写操作,其他用户都会看到。
    2.AFS中,对于一个用户写操作,以打开的用户不能看到其变化,只有等到写操作的用户关闭后再打开的用户才能看到变化。
    3.一个文件只要被共享,就不能被修改。

    计算机可能会遇到两个不安全问题:

    1.物理损坏问题。通过备份解决。

    2.访问。 通过访问控制解决。

    对于一个文件,只要允许访问,就必定存在保护的问题,我们需要通过控制访问即控制用户的操作权限。

    基本的操作在前面也讲过,比如读,写,执行,删除,添加,列出列表。对于高层的操作,比如复制,就可以用读来写出。让我想到了数据库。关系代数表达式的基本操作~选择,投影,并,笛卡儿积,差,重命名。其他高层的一些操作比如交,除,都可以用基本操作替代。

    对于访问控制的最容易想到的解决方法是给每个文件加上一张表,称为访问控制表ACL。列出能够访问的用户名。但是这个方法的直观缺点就是长度问题。

    解决方案就是精简访问列表:

    1.拥有者:最高等级。

    2.组:需要某种类似访问组成的组。

    3.其他。

     

    展开全文
  • 操作系统基本接口函数

    千次阅读 2018-08-01 16:16:36
    文件描述符: 操作系统通过一个整数代表打开的文件,这个整数就被称为文件描述符,windows上称为文件的句柄,进程能够打开的文件描述符的范围[0,1024] ,我们可以用ulimit-n查看...操作系统提供的基本接口函数:op...

    文件描述符:

    操作系统通过一个整数代表打开的文件,这个整数就被称为文件描述符,windows上称为文件的句柄,进程能够打开的文件描述符的范围[0,1024] ,我们可以用ulimit-n查看。有三个文件描述符进程一创建时就打开的

    标准输入stdin:0              标准输出stdout:1             标准错误stderroe:2 

    操作系统提供的基本接口函数:open 、read、write、close

    open函数:(两个功能,打开文件、创建文件)

    1.int open(const char *path,int flags);

    path为要打开的文件,flags为打开方式(读/写/读写),功能为打开文件,失败返回-1,成功则返回文件描述符的值

    O_RDONLY:读方式

    O_WRONLY:写方式

    O_RDWR:读写方式

    具体使用代码:

      1 #include<stdlib.h>
      2 #include<stdio.h>
      3 #include<unistd.h>
      4 #include<fcntl.h>
      5 int main()
      6 {
      7     int fd=open("open.c",O_RDONLY);
      8     if(fd==-1)
      9     {
     10         perror("open");
     11     }
     12     else
     13     {
     14         printf("ok!");                                                      
     15     }
     16     close(fd);
     17 }
    

    2.int open(const char*path,int flags,mode_t mode)

    mode为创建文件所赋予的权限一般为0644,flags:O_CREAT|三种方式|O_EXCL,path为要创建的文件名

    O_EXCL只能和O_CREAT连用,以确保不会创建重复的文件

    O_TRUNC:打开文件后清空文件

    O_APPEND:往文件中追加内容

    此外我们还要知道:创建文件权限要受到umask影响,系统重复创建文件不会覆盖原来的文件内容

    具体使用代码:

      1 #include<stdio.h>
      2 #include<unistd.h>
      3 #include<fcntl.h>                                                           
      4 #include<stdlib.h>
      5 int main()
      6 {
      7     int fd=open("hello",O_CREAT|O_RDWR,0644);
      8     if(fd==-1)
      9     {
     10         perror("open");
     11         exit(1);
     12     }
     13     else
     14     {
     15         printf("creat success");
     16     }
     17     close(fd);
     18 }
    

    read函数:

    int  read(int fd,char *buf,size_t len);

    fd为文件描述符,读取到buf所指向的空间,空间的大小为len,返回值为实际读取的字节数。并非一定要读够len,当小于len时读够就结束,失败返回-1,读取到文件结尾返回0

    具体使用代码:

     1 #include<stdio.h>                                                           
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<fcntl.h>
      6 int main()
      7 {
      8     int fd=open("read.c",O_RDONLY);
      9     if(fd==-1)
     10     {
     11         perror("open");
     12         exit(1);
     13     }
     14     else
     15     {
     16         while(1)
     17         {
     18             char buf[20]={};
     19             int r=read(fd,buf,10);
     20             if(r==-1)
     21             {
     22                 perror("read");
     23                 exit(1);
     24             }
     25             else if(r==0)
     26             {
     27                 printf("finsh read");
     28                 break;
     29             }
     30             else
     31             {
     32                 printf("[%s]\n",buf);
     33             }
     34         }
     35     }
     36     close(fd);
     37 }                                                                           
    

    write函数:

    int write (int fd,const char *buf,size_t len);

    往fd所指向的文件中写入数据,数据的起始地址为buf,大小为len,失败返回-1,正确返回写入的字节数

    具体使用代码:

      1 #include<stdio.h>                                                           
      2 #include<unistd.h>
      3 #include<string.h>
      4 #include<fcntl.h>                                                       
      5 #include<stdlib.h>
      6 int main()
      7 {
      8     int fd=open("hello",O_CREAT|O_RDWR,0644);
      9     if(fd==-1)
     10     {
     11         fd=open("hello",O_RDWR);
     12         if(fd==-1)
     13         {
     14             perror("open");
     15             exit(1);
     16         }
     17     }
     18         char *msg="this is enjoyselflzz";
     19         int r=write(fd,msg,strlen(msg));
     20         if(r==-1)
     21         {
     22             perror("write");
     23         }
     24         else
     25         {
     26             printf("len=%d,r=%d\n",strlen(msg),r);
     27         }
     28          close(fd);
     29 }

    close函数:

    int close(int fd)

    关闭文件,为了释放资源,如果不close()那就要等到垃圾回收时,自动释放,但垃圾回收的实时机是不确定的,也无法控制的。如果程序是一个服务,或者时需要很长时间才能执行完,或者很大并发执行,就可能导致资源被耗尽,也可能导致死锁。

    温馨提示:open()完记得要close()!

    操作文件的接口函数:

    FILE*fp=fopen(“文件名”,“方式rwa+”)打开文件

    fgetc(fp)表示从文件里读取一个字符------------------------------------>fputc()

    fgets(buf,len,fp)从文件中读取一行-------------------------------------->fputs()

    fscanf(fp,"%s",buf)从文件里按照给定的格式读取内容装入buf中------------------------------------->fprintf()

    fread(buf,size,nnumb,fp) buf是读入的文件,size是一个元素的大小,nnum是元素个数,fp所读的文件---------> fwrite()

    fclose(fp)

    展开全文
  • 文件系统-操作系统实验

    千次阅读 2020-06-14 15:17:35
    1、熟悉Linux文件系统的文件和目录结构,掌握Linux文件系统基本特征; 2、模拟实现Linux文件系统的简单I/O流操作:备份文件。 二、实验内容 1、浏览Linux系统根目录下的子目录,熟悉每个目录的文件和功能; 2、...
  • 文件系统操作系统)

    千次阅读 2015-10-04 14:06:15
    现代操作系统有多种文件系统类型(如FAT32、NTFS、 ext2、ext3、ext4等),因此文件系统的层次结构也不尽相同。图4-11是一种合理的层次结构。 图4-11文件系统层次结构 1) 用户调用接口 文件系统为用户提供与文件...
  • 操作系统——文件系统

    千次阅读 多人点赞 2015-02-02 09:17:40
    文件是由操作系统来管理的,包括文件的结构、文件的命名、文件的使用、文件的保护和文件的实现等,这些都是在...对于他们来说,他们关心的是文件系统所提供的对外的用户接口,包括文件如何命名、如何保护、如何访问
  • 命令语言:以命令为基本单位,指示操作系统完成特定的功能;由诸多命令组成了命令集,完整的命令集包含了操作系统提供给用户的全部功能。 命令行方式 批命令方式 交互方式:用户输入命令、终端处理程序接收命令、在...
  • 操作系统学习笔记:文件系统实现

    千次阅读 2015-11-10 23:36:19
    文件系统有两个不同的设计问题:1、如何定义文件系统对用户的接口,涉及到文件及其属性、文件允许的操作、组织文件的目录结构;2、创建数据结构和算法将逻辑文件系统映射到物理外存设备上。目前有许多文件系统在使用...
  • 操作系统实验四:文件系统

    千次阅读 2020-06-20 19:15:41
    1、熟悉Linux文件系统的文件和目录结构,掌握Linux文件系统基本特征; 2、模拟实现Linux文件系统的简单I/O流操作:备份文件。 二、实验环境 Linux系统 三、实验内容 1、浏览Linux系统根目录下的子目录,熟悉每个...
  • 操作系统基础知识复习总结

    万次阅读 多人点赞 2018-06-11 13:55:23
    操作系统 操作系统概述 操作系统作用 存储管理 处理机管理 设备管理 文件管理 用户接口 操作系统的定义 是管理和控制计算机系统中各种硬件和软件资源、合理地组织计算机工作流程的...
  • linux操作系统 第09章 操作系统接口

    千次阅读 2020-07-21 11:26:36
    第9章 操作系统接口  9.1 操作系统接口概述9.1.1 作业与作业调度  按操作系统的术语,用户是以提交“作业”的形式来使用系统的。因此,操作系统接口可以看作是用户提交作业的接口。  1. 作业的概念  作业...
  • 深入理解操作系统原理之文件系统

    万次阅读 多人点赞 2017-07-04 15:15:39
    操作系统对系统的软件资源(不论是应用软件和系统软件)的管理都以文件方式进行,承担这部分功能的操作系统称为文件系统。 1、文件 计算机系统对系统中软件资源:无论是程序或数据、系统软件或应用软件都以文件...
  • //思路:用户登录文件系统,然后创建、打开、读、写、关闭、删除文件 import java.io.*; import java.util.*; public class Main{ public static void main(String[] args){ Scanner scan = new Scanner...
  • 目录 文章目录目录Linux 文件系统目录结构文件系统类型虚拟文件系统文件类型 Linux 文件系统 文件系统是文件存放在磁盘...一个操作系统的运行离不开对文件的操作,因此必然要拥有并维护自己的文件系统。 目录结构 和...
  • 文件系统基本概念-&amp;amp;amp;gt;文件系统磁盘布局-&amp;amp;amp;gt;文件系统IO系统-&amp;amp;amp;gt;MQ队列机制-&amp;amp;amp;gt;IO管控。 下面开始简单介绍一下文件系统的一些基本概念,大部分...
  • 操作系统:文件系统的实现

    千次阅读 2020-12-31 14:39:13
    目录一、文件系统结构二、文件系统实现1.概述2.虚拟文件系统三、目录实现1.线性列表2.哈希表四、磁盘空间的分配方法1.连续分配2.链接分配3.索引分配五、磁盘空闲空间的管理1.位向量2.链表3.组4.计数六、文件系统的...
  • 文件系统调用和Linux文件系统基础

    千次阅读 2016-07-05 17:20:50
    文件系统调用和Linux文件系统基础keywords fdisk、LBA、CHS、MBR、super struct、directory、file、inode、inode table、block、file descriptor、file descriptor table、open file descriptor、open file table、...
  • 文章目录6.1 用户接口6.2 其他特殊操作系统6.2.1 嵌入式操作系统6.2.2 分布式操作系统 6.1 用户接口 一、用户接口的发展 早期操作系统对外提供的接口很简陋,功能也单一,包括脱机的作业控制语言(或命令)和联机的...
  • 操作系统接口shell

    千次阅读 2016-07-06 14:16:26
    操作系统与外部最主要的接口就叫做shell。shell是操作系统最外面的一层。shell管理你与操作系统之间的交互:等待你输入,向操作系统解 释你的输入,并且处理各种各样的操作系统的输出结果。 shell提供了你与操作系统...
  • 为了提供对磁盘的高效且便捷的访问,操作系统通过文件系统来轻松地存储、定位、提取数据。文件系统有两个设计问题。 ①定义文件系统对用户的接口 ②创建数据结构和算法来将逻辑文件系统映射到物理外存设备上。
  • Linux操作系统基础(完结)

    万次阅读 多人点赞 2016-03-09 21:00:45
    三、Linux文件系统及文件基础 四、Linux操作系统命令使用基础 五、Linux应用程序的安装与卸载基础 五、用户及进程 六、相关信息查询 七、网络配置 八、Linux应用程序的安装与卸载基础 九、vim
  • 文章目录1.实验目的2....熟悉Linux操作系统的命令接口、图形接口和程序接口。提高学生的动手能力。 2.实验内容和要求 实验内容 设计一个简单的程序; 对该程序进行编译,并运行。 实验要求 (1)熟悉...
  • Hadoop文件系统接口(二)

    千次阅读 2014-01-19 00:04:41
    HDFS全称是Hadoop Distributed System。HDFS是为以流的方式存取大文件而设计的。...hadoop提供了许多文件系统接口,用户可使用URI方案选取合适的文件系统来实现交互。 (1)接口  hadoop是使用Java编
  • 操作系统实验:文件系统

    千次阅读 2019-06-14 13:21:29
    本实验要求在模拟的I/O系统之上开发一个简单的文件系统。用户通过create, open,read等命令与文件系统交互。文件系统把磁盘视为顺序编号的逻辑块序列,逻辑块的编号为0至L −1。I/O系统利用内存中的数组模拟磁盘。 ...
  • 操作系统的功能和目标(1)作为计算机系统资源的管理者1️⃣处理器(CPU)管理2️⃣存储器管理3️⃣文件管理4️⃣设备管理(2)作为用户与计算机硬件系统之间的接口1️⃣命令接口2️⃣程序接口(3)作为扩充机器...
  • 操作系统基本概念

    千次阅读 2021-02-25 10:38:59
    操作系统基本概念 操作系统定义 直接拉取书本上的概念进行总结: 操作系统控制和管理计算机的软件和硬件,合理组织计算机的工作和资源分配,以提供用户和其他软件方便的接口和环境,是最基本的系统软件。 操作系统...
  • 操作系统文件管理

    万次阅读 多人点赞 2011-01-06 18:27:00
    在现代计算机系统中,要用到大量的程序和数据,因内存容量有限,且不能长期保存,故而平时总是把它们以文件的形式存放在外存中,需要时再随时将它们调入内存。如果由用户直接管理外存上的文件,不仅要求用户熟悉外...
  • Unix操作系统基础3-Unix文件系统

    千次阅读 2006-06-18 13:16:00
    Unix文件系统文件的概念文件是字节流。 文件类型-普通文件-目录文件:目录内文件名的列表-特殊文件:代表系统中的设备,在/dev目录 路径名目录操作相关概念-用户主目录-当前目录,工作目录 相关命令- pwd (print ...
  • 现代操作系统有多种文件系统类型(如FAT32、NTFS、 ext2、ext3、ext4等),因此文件系统的层次结构也不尽相同。图4-11是一种合理的层次结构。   图4-11文件系统层次结构 1) 用户调用接口 文件系统为用户提供与...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 737,831
精华内容 295,132
关键字:

文件系统基本操作接口