大家好,又见面了,我是你们的朋友全栈君。
文件是一种抽象机制,它提供了一种方式用来存储信息以及在后面进行读取。可能任何一种机制最重要的特性就是管理对象的命名方式。
对用户来说,文件的时间必须隐藏信息的保存方式和位置以及磁盘的实际工作。
文件命名规则对于不同的操作系统来说是不一样的,但是所有现代操作系统都允许使用 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 | 压缩存档 |
文件可以按几种不同方式构成。通常的三种
对于无结构的字节序列,操作系统不知道也不关心文件中是什么。它所看到的全部都是字节。任何意义都必须由用户级程序指定。UNIX和Windows都是用盖房似乎
记录序列把文件看作定长的记录序列
树:用于商业数据处理
三种类型的文件 a. 字节序列 b. 记录序列 c. 树
一种分类:
UNIX的一种分类:
a. 可执行文件 b. 存档文件
早期的操作系统只提供顺序存取(sequential access)。在这些系统中,进程可以从文件开始处顺序读取文件中所有字节或者记录,但不能够略过某些内容,也不能够非顺序读取。
用磁盘存储文件后,我们可以非顺序地读取文件中的字节或记录,或者根据关键字而不是位置来存取记录。能够以任何顺序读取的文件叫做随机存取文件(random access file)。
顺序存取
随机存取
域 | 含义 |
---|---|
保护 | 谁能访问该文件,以何种方式访问 |
口令 | 访问该文件所需口令 |
创建者 | 文件创建者的ID |
拥有者 | 当前拥有者 |
只读标志 | 0表示读写,1表示只读 |
隐藏标志 | 0表示正常,1表示不在列表中显示 |
系统标志 | 0表示正常文件,1表示系统文件 |
存档标志 | 0表示已备份过,1表示需要备份 |
ASCII/二进制 | 0表示ASCII文件,1表示二进制文件 |
随机存取标志 | 0表示只能顺序存取,1表示随机存取 |
临时标志 | 0表示正常,1表示在进程退出时删除文件 |
锁标志 | 0表示未锁,非零表示已锁 |
记录长度 | 一条记录的字节数 |
关键字位置 | 每条记录中关键字偏移 |
关键字长度 | 关键字域的字节数 |
创建时间 | 文件创建的日期和时间 |
最后存取时间 | 文件最后存取的日期和时间 |
最后修改时间 | 文件最后修改的日期和时间 |
当前长度 | 文件字节数 |
最大长度 | 文件最大允许字节数 |
文件用于存储信息便于以后检索。不同系统提供了不同的操作进行存储和检索。下面是一些与文件有关的最常用的系统调用:
#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;
}
为了记录文件信息,文件系统通常有目录或者文件夹
在许多系统中,目录本身就是文件
目录包括其组织、属性以及作用于其上的操作
目录系统的最简单形式就是使用一个目录包含所有的文件
有时候,称之为根目录,不过,由于只有一个目录,名字无关紧要
在早期的个人计算机上,这种系统非常普遍,部分原因是只有一个用户
非常有趣的是,世界上最大的超级计算机CDC 6600,对于所有文件也只有一个目录,尽管它同时有多个用户使用
这个决断无疑是想保持软件设计的简单
单层目录系统
双层目录系统
图中字母表示目录和文件的所有者
双层目录系统消除了不同用户之间的文件名冲突,但仍然难以使有很多文件的用户感到满意
用户常常需要把文件按某种逻辑方式组织起来
最终我们需要的是一般的层次(即目录树)。采用层次结构,每个用户可以拥有多个所需的目录,自然地组织他们的文件。
目录树
使用目录树来组织文件系统时,需要某种方法指明文件名。
绝对路径实例:
相对路径实例:
每个目录中有两个特殊的目录项:
相对于文件的系统调用而言,各个系统中用于管理目录的系统调用差别更大。
以上列出了最主要的系统调用。但还有一些其他调用,比如管理与目录相关的保护信息的系统调用。
以上从用户角度考察文件和目录
以下从实现者角度考察文件系统
用户关心的是文件时怎样命名的、可以进行哪些操作、目录树时怎么样的以及类似的界面问题
而实现者感兴趣的时文件和目录时怎样存储的、磁盘空间时怎样管理的以及怎样使系统有效而可靠地工作等
MBR:磁盘的0号扇区叫做MBR(Master Boot Record,主引导记录),用于启动计算机
分区表:位于MBR的尾部。多数磁盘可以划分为一个或多个分区,该表给出了每个分区的起点和重点地址。表中有一个分区被标记为活动的
计算机启动:BIOS读取并执行MBR,MBR程序首先确定活动分区,读入其第一块,即引导块(boot block),并执行它。引导快中的程序载入包含该分区中的操作系统
不同的文件系统磁盘布局不相同
最简单的分配方案是把每个文件作为连续数据块存储在磁盘上。所以,在块大小为1K的磁盘上,50K的文件要连续分配50个连续的块
该分配方案有两大优势
缺点:不能预知文件的长度,会造成磁盘碎片
适用于CD-ROM,文件长度已知且在使用中不会改变
目录项:文件名+起始块号+长度
a. 分配给7个文件的连续磁盘空间 b. 文件D、F被删除后的磁盘状态
存储文件的第二种方法是为每个文件构造磁盘块的链表。每个块的第一个字作为指向下一块的指针,块的其他部分存放数据。
优点:这类方法可以利用每个磁盘块。不会因为磁盘碎片而浪费存储空间
缺点:指针占用块空间;顺序读取文件非常方便,但是随机存取相当缓慢
将文件保存为磁盘块的链表
目录项:文件名+起始块号+长度
链表分配使用内存中的一个文件分配表
记录各个文件分别包含哪些磁盘块的方法是给每个文件赋予一张称为i-节点的小表,其中列出了文件属性和文件中各块在磁盘上的地址
目录项:文件名+I节点号
UNIX的i-节点
打开文件时,操作系统利用用户给出的路径名找到相应目录项,目录项提供了查找文件磁盘块所需要的信息。中目录系统的主要功能是把ASCII文件名映射成查找文件数据所需的信息。
目录项的设计
a. 包含固定大小项的简单目录,目录项中有磁盘地址和属性 b. 目录中的每一项只是对i-节点的引用
在目录中处理长文件名的两种方法 a. 行方式 b. 堆方法
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/167059.html原文链接:https://javaforall.cn
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有