大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
4.1 文件
4.1.1 文件命名
文件是一种抽象机制,它提供了一种方式用来存储信息以及在后面进行读取。可能任何一种机制最重要的特性就是管理对象的命名方式。
对用户来说,文件的时间必须隐藏信息的保存方式和位置以及磁盘的实际工作。
文件命名规则对于不同的操作系统来说是不一样的,但是所有现代操作系统都允许使用 1 – 8 个字母的字符串作为合法文件名。
扩展名 | 含义 |
---|---|
file.bak | 备份文件 |
file.c | C源程序 |
file.f77 | Fortran 77程序 |
file.gif | Compuserve 图形转换格式图像 |
file.hlp | 帮助文件 |
file.html | 万维网超文本标记语言文档 |
file.mpg | 用MPEG标准编码的电影 |
file.o | 目标文件(编译器输出,但未连接) |
file.ps | Postscript文件 |
file.tex | 用于TEX格式化程序的输入 |
file.txt | 一般文档文件 |
file.zip | 压缩存档 |
4.1.2 文件结构
文件可以按几种不同方式构成。通常的三种
- 字节序列
- 记录序列
- 树
对于无结构的字节序列,操作系统不知道也不关心文件中是什么。它所看到的全部都是字节。任何意义都必须由用户级程序指定。UNIX和Windows都是用盖房似乎
记录序列把文件看作定长的记录序列
树:用于商业数据处理
三种类型的文件
a. 字节序列
b. 记录序列
c. 树
4.1.3 文件类型
一种分类:
- 普通文件:包含用户信息的文件
- ASCII文件:可显示和打印
- 二进制文件:有一定的内部结构,如可执行文件等
- 目录:系统文件,用于维护文件系统的结构
UNIX的一种分类:
- 字符特殊文件:与I/O相关的,用于建模诸如终端、打印机和网络等的串行I/O设备
- 块特殊文件:用于磁盘建模
a. 可执行文件
b. 存档文件
4.1.4 文件存取
早期的操作系统只提供顺序存取(sequential access)。在这些系统中,进程可以从文件开始处顺序读取文件中所有字节或者记录,但不能够略过某些内容,也不能够非顺序读取。
用磁盘存储文件后,我们可以非顺序地读取文件中的字节或记录,或者根据关键字而不是位置来存取记录。能够以任何顺序读取的文件叫做随机存取文件(random access file)。
顺序存取
- 从起点读取所有字节/记录
- 不能跳过,可以倒带或者倒退
- 对于磁带媒介比较方便
随机存取
- 以任意次序读取字节/记录
- 是数据库系统的根本所在
- 可以下列方式读取文件
- 移动文件标记(seek),然后读取
- 读取,然后移动文件标记
4.1.5 文件属性
域 | 含义 |
---|---|
保护 | 谁能访问该文件,以何种方式访问 |
口令 | 访问该文件所需口令 |
创建者 | 文件创建者的ID |
拥有者 | 当前拥有者 |
只读标志 | 0表示读写,1表示只读 |
隐藏标志 | 0表示正常,1表示不在列表中显示 |
系统标志 | 0表示正常文件,1表示系统文件 |
存档标志 | 0表示已备份过,1表示需要备份 |
ASCII/二进制 | 0表示ASCII文件,1表示二进制文件 |
随机存取标志 | 0表示只能顺序存取,1表示随机存取 |
临时标志 | 0表示正常,1表示在进程退出时删除文件 |
锁标志 | 0表示未锁,非零表示已锁 |
记录长度 | 一条记录的字节数 |
关键字位置 | 每条记录中关键字偏移 |
关键字长度 | 关键字域的字节数 |
创建时间 | 文件创建的日期和时间 |
最后存取时间 | 文件最后存取的日期和时间 |
最后修改时间 | 文件最后修改的日期和时间 |
当前长度 | 文件字节数 |
最大长度 | 文件最大允许字节数 |
4.1.6 文件操作
文件用于存储信息便于以后检索。不同系统提供了不同的操作进行存储和检索。下面是一些与文件有关的最常用的系统调用:
- CREATE: 创建没有任何数据的文件。
- DELETE: 删除文件以释放磁盘空间。
- OPEN :将文件属性和磁盘地址表载入主存,便于以后系统调用的快速存取。
- CLOSE: 关闭文件以释放内部表空间。
- READ:从文件中读取数据。一般,读出的数据来自当前位置。调用者必须指明需要读取多少数据,并且提供存放这些数据的缓冲区。
- WRITE:向文件中写入数据,写操作一般也是从当前位置开始。如果当前位置是文件末尾,文件长度增加。如果当前位置在文件中间,则现有数据被重写,并且永远丢失了。
- APPEND: 该调用是WRITE的限制形式,它只能在文件末尾添加数据。
- SEEK: 把当前位置指针指向文件中特定位置。
- GET ATTRIBUTES: 读取文件属性。
- SET ATTRIBUTES: 设置文件属性。
- RENAME: 改变现有文件的文件名。
使用文件系统调用的实例
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h> //fcntl.h是unix标准中通用的头文件,其中包含的相关函数有open,fcntl,shutdown,unlink,fclose等
#include <unistd.h> //是C和C++程序设计语言中提供对POSIX操作系统API的访问功能的头文件的名称
#define BUF_SIZE 4096
#define OUTPUT_MODE 0700
int main(int argc, char *argv[])
{
int in_fd, out_fd, rd_count, wt_count;
char buffer[BUF_SIZE];
if (argc != 3)
exit(1);
in_fd = open(argv[1], O_RDONLY); //O_RDONLY 以只读方式打开文件
if (in_fd < 0)
exit(2);
out_fd = creat(argv[2], OUTPUT_MODE);
if (out_fd < 0)
exit(3);
while (1)
{
rd_count = read(in_fd, buffer, BUF_SIZE);
if (rd_count <= 0)
break;
wt_count = write(out_fd, buffer, rd_count);
if (wt_count <= 0)
exit(4);
}
close(in_fd);
close(out_fd);
if (rd_count == 0)
exit(0);
else
exit(5);
return 0;
}
4.2 目录
为了记录文件信息,文件系统通常有目录或者文件夹
在许多系统中,目录本身就是文件
目录包括其组织、属性以及作用于其上的操作
4.2.1 一级目录系统
目录系统的最简单形式就是使用一个目录包含所有的文件
有时候,称之为根目录,不过,由于只有一个目录,名字无关紧要
在早期的个人计算机上,这种系统非常普遍,部分原因是只有一个用户
非常有趣的是,世界上最大的超级计算机CDC 6600,对于所有文件也只有一个目录,尽管它同时有多个用户使用
这个决断无疑是想保持软件设计的简单
单层目录系统
- 单层目录系统包含的4个文件,分别属于不同的人A、B和C
双层目录系统
图中字母表示目录和文件的所有者
4.2.2 层次目录系统
双层目录系统消除了不同用户之间的文件名冲突,但仍然难以使有很多文件的用户感到满意
用户常常需要把文件按某种逻辑方式组织起来
最终我们需要的是一般的层次(即目录树)。采用层次结构,每个用户可以拥有多个所需的目录,自然地组织他们的文件。
目录树
4.2.3 路径名
使用目录树来组织文件系统时,需要某种方法指明文件名。
-
第一种是每个文件都赋予一个绝对路径名(absolute path name),它由从根目录到文件的路径组成。绝对路径名总是从根目录开始,并且是唯一的。如果路径名的第一个字符是分隔符,那么这个路径就是绝对路径。
-
另一种文件名是相对路径名(relative path name)。它常和工作目录(也称作当前目录)的概念一起使用。用户可以指定一个目录作为当前的工作目录。这时,所有的路径名,如果不是从根目录开始,都是相对于工作目录的。相对路径往往更加方便,但是,它实现的功能和绝对路径完全一样。
绝对路径实例:
- 文件mailbox:/usr/ast/mailbox
- 文件dict:/usr/lib/dict
相对路径实例:
- 当前目录:/ 相对路径:usr/lib/dict
- 当前目录:/usr 相对路径:lib/dict
- 当前目录:/usr/lib 相对路径:dict
- 当前目录:/usr/ast 相对路径:../lib/dict
每个目录中有两个特殊的目录项:
- .(一个点):当前目录
- ..(两个点):父目录
4.2.4 目录操作
相对于文件的系统调用而言,各个系统中用于管理目录的系统调用差别更大。
- CREATE:创建目录。除了目录项“.”和“..”之外,目录内容为空。目录项“.”和“..”是系统自动放在目录中的。
- DELETE:删除目录。只有空目录可以被删除。只含有目录项“.”和“..”的目录都认为是空目录,这两个目录项是不能被删除的。
- OPENDIR:目录内容可被读取。同打开和读取文件一样,在读目录之前,必须打开目录。
- CLOSEDIR:关闭该目录以释放内部表空间。
- READDIR:返回打开目录的下一个目录项。
- RENAME:更改目录名。
- LINK:链接技术允许文件出现在多个目录中。这个系统调用指定一个存在的文件和一个路径名,并建立从文件到路径所指定的名字的链接。这样,同一文件可以在多个目录中出现。
- UNLINK:删除目录项。如果被解链的文件只出现在一个目录中,它从文件系统中被删除。如果它出现在多个目录中,只删除指定的路径名,其他路径名依然保留下来。
以上列出了最主要的系统调用。但还有一些其他调用,比如管理与目录相关的保护信息的系统调用。
4.3 文件系统的实现
以上从用户角度考察文件和目录
以下从实现者角度考察文件系统
用户关心的是文件时怎样命名的、可以进行哪些操作、目录树时怎么样的以及类似的界面问题
而实现者感兴趣的时文件和目录时怎样存储的、磁盘空间时怎样管理的以及怎样使系统有效而可靠地工作等
4.3.1 文件系统布局
MBR:磁盘的0号扇区叫做MBR(Master Boot Record,主引导记录),用于启动计算机
分区表:位于MBR的尾部。多数磁盘可以划分为一个或多个分区,该表给出了每个分区的起点和重点地址。表中有一个分区被标记为活动的
计算机启动:BIOS读取并执行MBR,MBR程序首先确定活动分区,读入其第一块,即引导块(boot block),并执行它。引导快中的程序载入包含该分区中的操作系统
不同的文件系统磁盘布局不相同
4.3.2 文件的实现
连续分配
最简单的分配方案是把每个文件作为连续数据块存储在磁盘上。所以,在块大小为1K的磁盘上,50K的文件要连续分配50个连续的块
该分配方案有两大优势
- 首先,简单、容易实现,记录每个文件用到的磁盘块简化为只需记住一个数字即可,也就是第一块的磁盘地址
- 其次,性能较好,在一次操作中,就可以从磁盘上读出整个文件
缺点:不能预知文件的长度,会造成磁盘碎片
适用于CD-ROM,文件长度已知且在使用中不会改变
目录项:文件名+起始块号+长度
a. 分配给7个文件的连续磁盘空间
b. 文件D、F被删除后的磁盘状态
链表分配
存储文件的第二种方法是为每个文件构造磁盘块的链表。每个块的第一个字作为指向下一块的指针,块的其他部分存放数据。
优点:这类方法可以利用每个磁盘块。不会因为磁盘碎片而浪费存储空间
缺点:指针占用块空间;顺序读取文件非常方便,但是随机存取相当缓慢
将文件保存为磁盘块的链表
目录项:文件名+起始块号+长度
使用内存表的链表分配
链表分配使用内存中的一个文件分配表
i-节点
记录各个文件分别包含哪些磁盘块的方法是给每个文件赋予一张称为i-节点的小表,其中列出了文件属性和文件中各块在磁盘上的地址
目录项:文件名+I节点号
UNIX V7文件系统
UNIX的i-节点
4.3.3 目录的实现
打开文件时,操作系统利用用户给出的路径名找到相应目录项,目录项提供了查找文件磁盘块所需要的信息。中目录系统的主要功能是把ASCII文件名映射成查找文件数据所需的信息。
目录项的设计
- 文件名
- 磁盘地址
- 文件属性
固定长度目录项
a. 包含固定大小项的简单目录,目录项中有磁盘地址和属性
b. 目录中的每一项只是对i-节点的引用
长度不固定的目录项
在目录中处理长文件名的两种方法
a. 行方式
b. 堆方法
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/167059.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...