模拟实现单级目录的FAT文件系统

合集下载

了解计算机文件系统NTFSFAT和HFS的区别

了解计算机文件系统NTFSFAT和HFS的区别

了解计算机文件系统NTFSFAT和HFS的区别计算机文件系统是操作系统用来组织和管理计算机存储设备上的文件和目录的一种机制。

在不同的操作系统中,常见的文件系统有NTFS、FAT和HFS。

本文将就NTFS、FAT和HFS三种文件系统进行比较,以帮助大家更好地了解它们之间的区别。

一、NTFSNTFS(New Technology File System)是微软公司开发的一种高性能、可靠性和安全性较强的文件系统。

NTFS首次被引入Windows NT操作系统,并一直沿用至今。

1.1 文件系统结构NTFS采用了一种分层次的文件系统结构。

它包含了主引导记录(MBR)、分区表、文件记录、文件分配表等重要的组成部分。

而数据存储则是通过将文件分割成不同的簇来管理。

1.2 特点和功能NTFS具有许多先进的特点和功能,例如:- 安全性:NTFS支持访问控制列表(ACL)和文件加密,可以对文件和目录进行更细粒度的权限控制。

- 可靠性:NTFS采用了日志和冗余技术,使得文件系统更加稳定和可靠。

- 容量:NTFS最大支持16EB(1EB=1024PB)的存储容量,能够满足大容量存储的需求。

- 文件压缩和加密:NTFS支持文件压缩和加密,可以提高存储效率并保护敏感数据的安全性。

二、FATFAT(File Allocation Table)是一种较早的文件系统,最初是由微软开发的。

FAT文件系统广泛应用于早期的Windows操作系统和一些移动存储设备中。

2.1 文件系统结构FAT文件系统采用了一种比较简单的存储结构,它通过FAT表来管理文件和目录。

FAT表是一个记录簇号和下一个簇号之间对应关系的查找表。

2.2 特点和功能FAT文件系统具有以下特点和功能:- 简单易用:FAT文件系统结构简单,易于实现和维护。

- 兼容性好:FAT文件系统具有较好的兼容性,可以在不同操作系统之间进行文件共享和传输。

- 存储限制:FAT文件系统的文件大小限制为4GB,对于大容量存储设备来说可能不够满足需求。

解释什么是文件系统并介绍一下常见的文件系统

解释什么是文件系统并介绍一下常见的文件系统

解释什么是文件系统并介绍一下常见的文件系统文件系统是计算机系统中用来管理和组织计算机存储设备上文件和目录的一种机制。

它通过一系列的算法和数据结构将文件和目录组织在存储设备上,并提供访问、读写、修改、删除等操作。

文件系统可以是硬件依赖的,也可以是独立于硬件的,在不同的操作系统中也可能有不同的实现方式。

一、文件系统的概念和作用文件系统是操作系统中的一个重要组成部分,它为用户和程序提供了一个统一的接口,使得用户能够方便地管理自己的文件和数据。

文件系统通过文件名、路径和索引等方式来唯一标识和定位文件,使得用户能够按照自己的需求轻松地组织和管理文件。

文件系统的作用主要有以下几个方面:1. 存储管理:文件系统负责将文件和目录存储在物理设备上,并管理存储空间的分配和释放,确保文件的完整性和可靠性。

2. 访问控制:文件系统通过对文件和目录的权限设置和访问控制列表,保护用户的数据安全,确保只有被授权的用户能够访问和修改文件。

3. 文件组织:文件系统提供了一种逻辑上的文件组织方式,如目录树结构、文件扩展名等,使得用户能够按照自己的需求进行文件的分类和组织。

4. 文件操作:文件系统提供了一系列的文件操作接口,如打开、关闭、读写、删除等,方便用户对文件进行各种操作。

二、常见的文件系统类型1. FAT文件系统:FAT(File Allocation Table)文件系统是由微软开发的一种常见的文件系统类型。

它包括FAT12、FAT16和FAT32等多个版本,主要用于MS-DOS、Windows 95/98、Windows ME等操作系统中。

FAT文件系统采用了简单的文件分配表来管理磁盘上的文件和空闲空间,具有兼容性好、速度快的特点,但对单个文件的最大大小和文件名的长度有一定限制。

2. NTFS文件系统:NTFS(New Technology File System)文件系统是微软开发的一种高级文件系统类型,用于Windows NT系列、Windows 2000/XP/7/8/10等操作系统中。

Fatfs文件系统2015-04

Fatfs文件系统2015-04

2015-04-18FATFS文件管理系统一、FATFS简介FATFS 是一个完全免费开源的FAT 文件系统模块,专门为小型的嵌入式系统而设计。

它完全用标准 C 语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM 等系列单片机上而只需做简单的修改。

它支持FATl2、FATl6 和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8 位单片机和16 位单片机做了优化。

FATFS 的特点有:✧ 代码量少、效率高✧ 多种配置选项✧ 支持多卷(物理驱动器或分区,最多10 个卷)✧ 多个ANSI/OEM 代码页包括DBCS✧ 支持长文件名、ANSI/OEM 或Unicode✧ 支持RTOS✧ 支持多种扇区大小✧ 只读、最小化的API 和I/O 缓冲区等二、FATFS层次结构图最顶层是应用层,使用者无需理会FATFS 的内部结构和复杂的FAT 协议,只需要调用FATFS 模块提供给用户的一系列应用接口函数,如f_open,f_read,f_write 和f_close 等,就可以像在PC 上读/写文件那样简单。

中间层FATFS 模块,实现了FAT 文件读/写协议。

FATFS 模块提供的是ff.c 和ff.h。

除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。

需要我们编写移植代码的是FATFS 模块提供的底层接口,它包括存储媒介读/写接口(disk I/O)和供给文件创建修改时间的实时时钟。

三、FATFS源码1.源码下载(1)在/fsw/ff/00index_e.html下载FatFs源码R0.10b版本;(2)打开压缩包,里面有doc和src两个文件夹,doc是对FatFs的一些介绍及更新说明,src为FatFs的源码;2.FatFs源码介绍(1)与硬件平台无关的文件✧ffconf.h FATFS 模块配置文件✧ff.h FATFS 和应用模块公用的包含文件✧ff.c FATFS 模块✧diskio.h FATFS 和disk I/O 模块公用的包含文件✧interger.h 数据类型定义✧option 可选的外部功能(比如支持中文等)(2) 与硬件平台相关的文件✧diskio.c FATFS 和disk I/O 模块接口层文件(3) 移植时,重要的选项配置✧_FS_TINY。

FAT文件系统读写程序

FAT文件系统读写程序

经过一个多月的努力,终于完成了fat文件系统的读写函数。

期间由于过年,杂事较多,所以一再推迟。

起初是模仿zlgfs,但当写到一半时觉得这样构架很难写。

于是又返工,重新设计,十分郁闷。

到最后从中能找到zlgfs影子的地方也就是几个结构体而已。

虽然也有缓冲区,但其算法已经是比zlgfs复杂很多,是参考linux的缓冲区算法的,查找使用的是一个双向循环链表和一个hash表,弄了好久才把主要的bug除掉。

总之,主要就是实现了在fat16文件系统中的多级目录,及文件目录的读写,创建。

最后还写了一个文本文件的读写和bmp图片的读写,结合我以前在这个开发板上做的gui,实现了触摸屏显示24位bmp图片的功能。

我测试时,只要在sd卡上存储上24位bmp图片就可以在lcd上显示,十分方便。

其中包含fat文件系统读写程序在EasyFS目录中,此源代码是ads1.2工程,是在fs2410开发板上的。

点击此处下载ourdev_418380.rar(文件大小:3.75M)(原文件名:EasySystem_2. rar)点击此处下载 ourdev_612887.rar(文件大小:3.75M) (原文件名:EasySystem_2. rar)(原文件名:ourdev_596204.JPG)引用图片(原文件名:1--磁盘信息.jpg)这是在添加文件系统的磁盘驱动程序时在串口中打印的磁盘信息。

(原文件名:ourdev_612928.jpg)引用图片(原文件名:2.jpg)这是测试文件显示和创建,先在串口中打印文件"11111\\maomaob.txt",然后创建文件"mao\\shuang\\pei\\chengmao.txt",并向其中写入"mao mao cheng pe i"(原文件名:ourdev_612929.jpg)引用图片(原文件名:2--创建一个文本文件.jpg)(原文件名:ourdev_612930.jpg)引用图片(原文件名:3.jpg)这个上面的图标也是在存储在sd卡中的,其中左边和黑白条纹就是使用下面的这段代码创建的bmp图片。

FAT文件系统的组织结构

FAT文件系统的组织结构

FAT文件系统的组织结构 1. 软盘数据的逻辑存储 软盘无须低级格式化和分区操作,只需用FORMAT命令做高级格式化即可。

经过格式化操作之 后,系统将在软磁盘上建立以下的数据结构: (1) 引导记录(DBR):位于0面0道1扇区,说明磁盘结构信息。

 (2) 文件分配表(FAT):用于记录磁盘空间的分配情况,指示硬盘数据信息存 放的柱面及扇区的信息指针。

其表项可以是以下四种表示方式之一: A.一个数字,代表指向另一个簇的指针。

 B.数字0,表示一个未使用的簇 C.一个坏扇区标记 D.文件结束标记符EOF (3) 文件根目录表FDT:一个指示以存入数据信息的索引。

记录磁盘上存储文 件的大小,位置,日期和时间等数据。

 (4) 数据区:存放数据信息。

 2. 硬盘中的数据组织 刚刚从厂商处购来的新硬盘既无任何数据,也不能写入任何数据,必须先进行低级格 式化,FDISK分区,FORMAT高级格式化后方可使用。

对硬盘的这一系列初始化工作,称之为 硬盘准备。

过程如下: 低级格式化---------------FDISK分区-------------------FORMAT高级格式化 (1)低级格式化:对硬盘划分磁道和扇区,在扇区的地址域上标注地址信息,并剔出坏磁 道。

 (2)FDISK:允许整个物理硬盘在逻辑上划分成多个分区(最多4个),以实现多个操作系 统共享硬盘空间。

如果将整个物理盘全部划归DOS/WINDOWS管理,则FDISK分区的作用是将一 个物理盘划分一个主分区和一个扩展分区,然后再将扩展分区划分成一个或多个逻辑盘。

在 硬盘上建立分区表的同时,FDISK把主引导记录MBR写到硬盘的主引导记录(柱面0,磁头0, 扇区1),并激活一个用户指定的分区。

 (3)FORMAT:在DOS分区空间划分逻辑扇区,生成DOS引导扇区(即逻辑0扇区)DBR,文件 分配表FAT和根文件目录表FDT。

 硬盘在DOS/WINDOWS的管理下,数据信息由MBR,DBR,FAT,FDT和数据区5 个部分组成。

fat文件系统

fat文件系统

FAT文件系统简介FAT(File Allocation Table)文件系统是一种广泛应用于计算机存储设备上的文件系统。

它最初在1977年由Microsoft开发,目前已经成为一种业界标准,被广泛支持使用。

FAT文件系统主要用于移动存储设备,如U盘、SD卡等。

它的设计简单、实现容易,占用资源较少,具有较好的兼容性和可移植性。

FAT文件系统支持在多个操作系统上读写数据,因此广泛应用于不同的设备和平台。

文件系统结构FAT文件系统由三个主要组成部分组成:文件分配表(File Allocation Table)、目录和文件数据区。

文件分配表(FAT)文件分配表是FAT文件系统的核心组成部分之一。

它记录了存储设备上每个文件的存储位置和状态。

FAT文件分配表以固定大小的簇为单位进行存储,每个簇的大小由文件系统的格式化参数决定。

文件分配表中的每个条目都对应一个簇,用于标记该簇的使用状态。

文件分配表通过链表的形式连接簇,形成文件的分配链。

通过遍历分配链,可以确定一个文件的存储位置和大小。

目录目录是FAT文件系统中用于存储文件和子目录信息的地方。

每个目录都有一个特定的条目用于描述该目录的属性和内容。

每个目录条目包含文件名、文件属性、创建日期等信息。

目录条目中还包含一个指向簇的条目,记录了文件或目录的起始簇号。

目录可以有多级,通过目录项中的指向上级目录的引用,可以在FAT文件系统中实现文件的层次结构。

文件数据区文件数据区是FAT文件系统中用于存储文件实际内容的地方。

它由一系列的簇组成,每个簇的大小由文件系统的格式化参数决定。

文件数据区通过文件分配表中的分配链来连接簇,形成文件的完整内容。

FAT文件系统的优缺点优点1.兼容性强:FAT文件系统可以在多个操作系统上读写数据,包括Windows、Linux、Mac等。

2.简单易用:FAT文件系统的设计简单,实现容易,易于开发和维护。

3.格式化兼容性好:FAT文件系统的格式化参数可以根据设备的特点进行调整,使之适应不同的存储介质。

文件系统fat和ntfs的原理

文件系统fat和ntfs的原理

文件系统fat和ntfs的原理FAT和NTFS是两种常见的文件系统,它们在计算机存储中起着重要的作用。

本文将分别介绍FAT和NTFS的原理,以及它们在文件存储中的特点和应用。

一、FAT文件系统的原理FAT(File Allocation Table)文件系统是最早应用于个人计算机的一种文件系统。

它的原理是将存储设备(如硬盘、U盘等)划分为若干个簇(Cluster),每个簇由若干个扇区(Sector)组成。

FAT 文件系统通过使用文件分配表(File Allocation Table)来记录每个簇的使用情况,以便于管理文件的存储和检索。

在FAT文件系统中,文件和目录被组织为一个层次结构,最顶层是根目录(Root Directory),根目录下可以包含文件和子目录。

每个文件或目录的相关信息,如名称、大小、属性等,都存储在目录项(Directory Entry)中。

而目录项的内容则通过文件分配表来确定文件或目录所占用的簇的位置。

FAT文件系统的优点之一是兼容性强,几乎所有操作系统都能够识别和访问FAT格式的存储设备。

此外,FAT文件系统还具有简单、易于实现和维护的特点。

二、NTFS文件系统的原理NTFS(New Technology File System)文件系统是微软公司开发的一种高级文件系统,它首次引入于Windows NT操作系统。

相对于FAT文件系统,NTFS具有更多的功能和更好的性能。

NTFS文件系统的原理是将存储设备划分为一个个的簇,每个簇的大小可以根据实际需求进行调整。

与FAT不同的是,NTFS使用了一种称为MFT(Master File Table)的结构来管理文件和目录的存储。

在NTFS文件系统中,每个文件和目录都有一个唯一的MFT记录,该记录存储了文件的元数据(如文件名、大小、权限等)以及文件的数据存储位置。

MFT记录中的数据可以直接存储在记录本身中,也可以通过指针指向其他数据簇。

实现实时FAT文件系统的一种简单方法

实现实时FAT文件系统的一种简单方法
t n 。 0 8 4 ( 6) 7 -7 . i s 2 0 , 4 1 : 0 2 o
Ab t a t M0 t e e d d mat d vc s n h ma k t o u e t e A f e y t m b c u e f i c mp t i t . w v r t e sr c : s mb d e s r e ie i t e r e n w s h F T i s se l e a s o t o ai l y Ho e e ,h s bi F wa n t e l e in d o AT s o w l d sg e t me t e l i r q i me t. h s ril p o o e a i l s l t n h t r al i r v s h e r a t me e u r e ns i T a t e r p s s smp e o ui t a g e t c o y mp o e t e r s o s i f t e AT f e s se wi o t u i g i o ai i t . ep ne t me o h F l y t m, t u h r n t c mp t ly i h t s bi Ke r s F y wo d : AT; l y tm ;e l t i fess e r a i me; o rs e AT;r e c u tr i d x c mp e s d F fe — l se n e
读写文件时文件系统经常需要进行文件逻辑簇号即这个文件中的第几个簇到物理簇号整个文件系统中的实际簇号的转换在这种链表结构中要进行这种转换必须对fat表进行遍历操作所以响应时间与读写位置呈线性关系时间复杂度为on其中n为要访问的数据所在的逻辑簇号
维普资讯
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

计算机《操作系统课程设计》任务书模拟实现单级目录、单级索引的索引文件系统一、课程设计的性质和目的操作系统课程设计是计算机专业的专业课程,通过课程设计使学生进一步巩固课堂所学知识,全面熟悉、掌握操作系统的基本设计方法和技巧,进一步提高分析问题、解决问题及上机操作能力,为将来从事计算机工作打下一定的专业基础。

二、设计课题模拟实现单级目录的FAT文件系统基本思路:用二进制文件空间模拟磁盘空间,用文件块操作模拟磁盘块操作。

基本设计要求:1、实现如下文件系统功能(过程或函数):a、打开文件系统FILE *OPENSYS(char *filename);b、关闭文件系统int CLOSESYS(FILE *stream);c、显示目录void LISTDIR(void);d、建立文件int FCREATE(char *filename);e、删除文件int FDELETE(char *filename);f、打开文件int FOPEN(char *filename);g、关闭文件int FCLOSE(int fileid);h、文件块读int FREAD(void *ptr, int n, int fileid);i、文件块写int FWRITE(void *ptr, int n, int fileid);j、判断文件结束int FEOF(int fileid);k、获取文件指针long FGETPOS(int fileid);l、设置文件指针int FSETPOS(int fileid, long offset);m、取得文件长度long FGETLEN(char *filename);2、提供文件系统创建程序3、有功能检测模块4、为简化程序设计,假定目录区域大小固定。

文件系统空间划分:可以使用的C语言文件操纵函数:FILE *fopen(const char *filename, const char *mode);int fclose(FILE *stream);int fseek(FILE *stream, long offset, int whence);long ftell(FILE *stream);size_t fread(void *ptr, size_t size, size_t n, FILE *stream);size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);目录一、程序的功能 (3)二、程序的基本设计思路 (3)三、主要的数据结构 (4)4.1创建文件流程图 (6)4.3 FREAD函数流程图 (8)五、程序调试及其运行结果 (9)六、设计总结与心得体会 (12)七、附录(源程序清单) (13)一、程序的功能该程序主要模拟实现单级目录的FAT文件系统,该系统要求能实现对文件的创建、删除、读、写、打开、关闭以及能显示目录等操作,在创建文件时,系统首先为新文件分配所需的外存空间,并且在文件系统的相应目录中,建立一个目录项,该目录项记录了新文件的文件名及其在外存中的地址等属性。

而当已经不再需要某个文件时,便可以把它从文件系统中删除。

这时执行的是与创建新文件相反的操作。

系统先从目录中找到要删除的文件项,使之成为空项,紧接着回收该文件的存储空间,用于下次分配。

通过读指针,将位于外部存储介质上的数据读入到内存缓冲区这样就实现了文件的读取,通过写指针,将内存缓冲区中的数据写入到位于外部存储介质上的文件中。

在开始使用文件时,首先必须打开文件。

这可以将文件属性信息装入内存,以便以后快速查用。

在完成文件使用后,应该关闭文件。

这不但是为了释放内存空间,而且也因为许多系统常常限制可以同时打开的文件数。

当创建文件时,先在目录表中查找是否存在此文件表,若存在则表示文件同名不能创建,否则在目录表中为此文件先建立一个目录项,保存文件的一些基本属性,如创建日期、大小、文件名等,并保存文件的首索引块扇区号,对文件读写也是先在目录项里查找文件是否存在,再根据文件的首索引块扇区号,查找对应块号中的内容对其进行读写操作,删除一个文件后回收为其分配的空间,并更新目录表、修改文件控制块。

显示目录项可以显示文件名、长度以及创建日期。

二、程序的基本设计思路模拟实现单极目录FAT的文件系统基本思路:用二进制文件空间模拟磁盘空间,用文件块操作模拟磁盘块操作。

在一个文件系统中对文件进行操作,实现文件的创建、读写等等操作。

在创建文件时先在目录项中进行查找,若创建的文件已存在,文件的创建首先检验目录是否为空,为空则把文件夹或文件连接到该目录下,不为空则把检查目录下是否有同名文件夹或文件,有则提示创建不成功,而文件夹打开是则把文件夹名称及其地址压入打开文件夹栈,文件关闭则把文件夹名称及其地址从打开文件夹栈中抛出。

文件夹和文件的删除,文件夹下没有打开的文件或文件没有打开才能删除,否则删除失败,每次操作成功都要更改目录和FCB信息。

该过程都保存在文件中,是对文件的操作。

本系统建于Windows平台,开发环境为WIN-TC。

三、主要的数据结构单级目录单级索引文件系统:常量#define BlockSize 512#define DirSize 32保留扇区结构struct ReserveBlock{int sysblocknum; /*文件系统总扇区数*/int resblocknum; /*保留扇区扇区数*/int mapblocknum; /*字节映像图扇区数*/int rootblocknum; /*根目录区扇区数*/char fillchar[BlockSize-4*sizeof(int)]; /*填充字节*/};目录结构struct DirBlock{char filename[11]; /*文件名限长11个字符*/char fillchar[DirSize-4*sizeof(int)-sizeof(long int)-11]; /*填充字节*/ long filelen; /*文件长度*/int year,month,day; /*定义年月日*/int firstindexaddr; /*文件首索引块扇区号*/};索引块结构struct IndexBlock{int dataaddr[BlockSize/sizeof(int)-1]; /*数据块块号数组*/int nextindexaddr; /*本文件下一索引块块号*/};索引节点结构struct IndexNode{struct IndexBlock block; /*索引块数据*/int blockaddr; /*本节点索引块块号*/struct IndexNode *nextnode; /*指向下一索引节点的指针*/};FCB(文件控制块)结构struct FCBBlock{int fileid; /*文件标识*/struct DirBlock fileinfo; /*目录信息*/long filepos; /*文件读写指针*/int fdtblockaddr; /*目录项所在块号*/int fdtblockindex; /*目录项所在块内序号*/struct FCBBlock *next; /*指向下一个文件控制块的指针*/struct IndexNode *firstindexnode; /*指向第一个索引节点的指针* /}四、相关流程图4.1创建文件流程图4.2删除文件流程图4.3 FREAD函数流程图五、程序调试及其运行结果图1图1为欢迎界面在输入系统块的数目后产生的界面,必须先要输入start开始运行文件系统才能完成建立文件(creat),显示文件目录(list),打开文件(open),关闭文件(close),删除文件(delete),写文件块(write),读文件块(read)等等操作图2输入start成功打开文件系统,再输入creat来创建文件,此图为创建成功后的界面图3图3表示输入list显示文件目录,如图所示创建了aaa,bbb,ccc三个文件图4图4显示的是成功打开和成功关闭文件图5输入read读取文件,可以设置读文件的初始位置以及读取文件的长度.图6 输入write写文件图7如图所示删除aaa,bbb,ccc三个文件六、设计总结与心得体会通过一个学期的学习,操作系统的课程设计也要结课了,总的来说经过这门课的学习收获还是挺大的,它不但使我更了解了课本知识,巩固了课本知识,而且也使我的编程能力有了一定的提高。

这次课程设计是对操作系统的一个总结和复习的过程,课设的过程是个自我探索、自我学习的过程,其中,我们不仅学到了专业的知识,也提升了自己的学习能力。

在此次课程设计中也遇到了不少的问题和困难,但是通过自己的努力和向同学讨教都把他一一的给解决了,总之,通过这次课程设计,是我对文件系统有了更深一部的了解,让我对文件系统不再陌生,当然自己还有很多不足的地方,希望自己在以后的学习过程中不断的改进,这样才能让自己进步,才能让自己更上一层楼。

七、附录(源程序清单)#include <stdio.h>#include <string.h>#include <stdlib.h>#define BlockSize 512#define DirSize 32#define RootSize 2struct ReserveBlock{int sysblocknum;/*文件系统总扇区数*/int resblocknum;/*保留扇区扇区数*/int fatblocknum;/*FAT表扇区数*/int rootblocknum;/*根目录区扇区数*/char fillchar[BlockSize-4*sizeof(int)];/*填充字节*/};struct DirBlock{char filename[11]; /*文件名限长11个字符*/char fillchar[DirSize-4*sizeof(int)-sizeof(long int)-11];/*填充字节*/long filelen; /*文件长度*/int year,month,day; /*日期*/int firstblockaddr; /*文件首块扇区号*/};struct FCBBlock{int fileid; /*文件标识*/long filepos; /*文件读写指针*/int fdtblockindex; /*目录项所在块内序号*/struct FCBBlock *next;/*指向下一个文件控制块的指针*/ };struct ReserveBlock sys1; /*保留块*/struct FCBBlock *fcb; /*fcb头指针*/ struct DirBlock fil[32],*dir; /*目录*/int *fat1; /*fat表头指针*/char *str,*ptr; /*读、写缓冲区首地址*/char fillchar[BlockSize]; /*填充字符*/FILE *fp; /*文件指针*/FILE *OPENSYS(char *filename) /*打开文件系统*/{ int i;fp=fopen(filename,"rb+");fread(&sys1,1,BlockSize,fp); /*读保留扇区*/fat1=(int *)malloc(sys1.fatblocknum*BlockSize);for(i=0;i<sys1.fatblocknum;i++) /*读fat表*/ fread(fat1+i*BlockSize,BlockSize,1,fp);fseek(fp,(sys1.fatblocknum+sys1.resblocknum)*BlockSize,0);dir=fil;for(i=0;i<sys1.rootblocknum;i++) /*读目录*/fread(dir+i*BlockSize/DirSize,BlockSize,1,fp);return fp;}int CLOSESYS(FILE *stream) /*关闭文件系统*/{ int i;fseek(stream,sys1.resblocknum*BlockSize,0);for(i=0;i<sys1.fatblocknum;i++) /*回写fat表*/ fwrite(fat1+i*BlockSize,BlockSize,1,stream);fseek(fp,(sys1.fatblocknum+sys1.resblocknum)*BlockSize,0);for(i=0;i<sys1.fatblocknum;i++) /*回写目录*/fwrite(dir+i*BlockSize/DirSize,BlockSize,1,fp);fclose(fp);return 0;}void LISTDIR(void) /*显示目录*/ { int i,flag=0;for(i=0;i<32;i++){ if(fil[i].firstblockaddr!=0){ if(flag==0)printf("文件名大小创建日期\n");flag=1;printf("%s%8ld%4d%4d%4d\n",fil[i].filename,fil[i].filelen,fil[i].year,fil[i].month,fil[i].day);} }}int FCREATE(char *filename) /*创建文件*/{int i,flag=0,j,k=0,flag1=0,flag2=0,a;int n,m;a=strlen(filename);if(a>10)return 1;for(i=0;i<sys1.rootblocknum*BlockSize/DirSize;i++) /*查找是否重名*/if(strcmp(filename,fil[i].filename)==0){printf("文件名已存在!\n");return 3;}for(i=(sys1.fatblocknum+sys1.resblocknum+sys1.rootblocknum);i<sys1.sysblocknum;i++) if(fat1[i]==0) /*查看是否有空的块*/flag++;if(flag==0){ printf("磁盘已满");/*统计结果为0,则磁盘已满*/return 0;}printf("空闲块数:%d\n",flag);printf("请输入文件长度:");for(j=0;j<32;j++)if(fil[j].firstblockaddr==0)break;while(1){scanf("%d",&dir[j].filelen);/*输入目录项中文件的长度*/n=(dir[j].filelen/BlockSize)+(dir[j].filelen%BlockSize?1:0);if(n<0||n>flag)/*文件长度小于0或大于空闲的空间*/{printf("文件太长!\n");printf("请重新输入:");}elsebreak;}for(i=(sys1.fatblocknum+sys1.resblocknum+sys1.rootblocknum);i<sys1.sysblocknum;i++) /*分配一块空间*/if(fat1[i]==0){ fat1[i]=-1;break;}dir[j].firstblockaddr=i+1;strcpy(dir[j].filename,filename); /*输入文件相关的信息*/dir[j].filename[a]='\0';printf("输入年份:");scanf("%d",&dir[j].year);printf("输入月份:");scanf("%d",&dir[j].month);printf("输入日期:");scanf("%d",&dir[j].day);return (0);}int FDELETE(char *filename) /*删除文件*/{int i,j,k,n,flag=1;struct FCBBlock *p;p=fcb;while(p) /*查看是否关闭了文件*/{ if(strcmp(filename,fil[p->fdtblockindex].filename)==0)return 1;elsep=p->next;}for(i=0;i<sys1.rootblocknum*BlockSize/DirSize;i++) /*查找是否存在要删除的文件*/if(strcmp(filename,fil[i].filename)==0){ flag=1;break;}if(flag==0)return 2;j=fil[i].firstblockaddr;while(1){k=fat1[j-1]; /*将要删除的文件的块用0填充*/fseek(fp,(j-1)*BlockSize,0);fwrite(&fillchar,1,BlockSize,fp);fat1[j-1]=0;if(k==-1)break;elsej=k;}memset(&fil[i],0,DirSize); /*将要删除的文件的目录用0填充*/return 0;}int FOPEN(char *filename) /*打开文件*/{int i,j=0,k,flag=0,id;struct FCBBlock *p,*q,*r;p=fcb;for(i=0;i<sys1.rootblocknum*BlockSize/DirSize;i++) /*查找要打开的文件是否存在*/if(strcmp(filename,fil[i].filename)==0){ flag=1;break;}if(flag==0)return 0;if(fcb==NULL){ fcb=(struct FCBBlock *)malloc(sizeof(struct FCBBlock));fcb->fileid=j+1;fcb->filepos=0;fcb->next=NULL;fcb->fdtblockindex=i;id=j+1;return id;}else{ while(fcb){j++;if(strcmp(filename,fil[fcb->fdtblockindex].filename)==0) /*判断是否已经打开*/return 0;q=fcb;fcb=fcb->next;}r=(struct FCBBlock *)malloc(sizeof(struct FCBBlock)); /*创建fcb*/r->fileid=j+1;r->filepos=0;r->next=NULL;r->fdtblockindex=i;q->next=r;}id=j+1;fcb=p;return id; /*返回打开的文件的标识fileid*/ }long FGETLEN(char *filename) /*获取文件的长度*/{ int i;for(i=0;i<sys1.rootblocknum*BlockSize/DirSize;i++)if(strcmp(filename,fil[i].filename)==0)return fil[i].filelen;return -1;}int FCLOSE(char *filename)/*关闭文件*/{ int flag=0;struct FCBBlock *f,*p;f=fcb;if(strcmp(filename,fil[fcb->fdtblockindex].filename)==0){ flag=1;fcb=fcb->next;p=fcb;while(p){p->fileid-=1;p=p->next;}return flag;}p=f;f=f->next;while(f){if(strcmp(filename,fil[f->fdtblockindex].filename)==0){ flag=1;p=f->next;/*p=p->next;*/while(p){ p=p->next;p->fileid-=1;}free(f);return flag;}p=f;f=f->next;}if(flag==0){ printf("The file has not open!\n'");return flag;}return 0;}int FREAD(char *str, int n, int fileid) /*读文件*/{ int m,i,j=0,k,l,len,n1,n2=0;struct FCBBlock *p;p=fcb;while(p) /*查找要读的文件的fcb*/{if(p->fileid==fileid)break;elsep=p->next;}if(p==NULL)return 1;len=fil[p->fdtblockindex].filelen;l=p->filepos;if((l+n)>len)return 2;j=(l/BlockSize)+(l%BlockSize?1:0); /*求文件指针所在文件的相对块号*/m=((l+n)/BlockSize)+((l+n)%BlockSize?1:0);k=fil[p->fdtblockindex].firstblockaddr;for(i=1;i<j;i++) /*求文件指针所在的块号*/k=fat1[k-1];str=(char *)malloc((m-j+1)*BlockSize+1); /*分配读取的缓冲区*/for(i=0;i<(m-j+1);i++) /*读文件*/{fseek(fp,(k-1)*BlockSize,0);fread(&str[i*BlockSize],BlockSize,1,fp);k=fat1[k-1];}str[n+l-(j-1)*BlockSize]='\0'; /*截断多读的内容*/if(l!=0)str=&str[l-(j-1)*BlockSize];p->filepos=n+l; /*修改文件指针*/printf("%s\n",str);return 0;}int FWRITE(char *ptr, int n, int fileid) /*文件写*/{long l;int m,i=0,j,k=0,num,flag=0,flag1=0,b,flag2=0;int n1,n2=0,n3,c;struct FCBBlock *p;char *st1,*st2;st1=(char *)malloc(BlockSize);p=fcb;while(p) /*查找文件的fcb*/{if(p->fileid==fileid)break;elsep=p->next;}if(p==NULL)return 1;l=p->filepos;n1=fil[p->fdtblockindex].firstblockaddr;while(n1!=-1){n2++;m=n1-1;n1=fat1[n1-1];}if((l+n)>n2*BlockSize) /*判断是否要追加空间*/{ n3=(l+n)/BlockSize+((l+n)%BlockSize?1:0)-n2; /*追加空间*/for(i=(sys1.fatblocknum+sys1.resblocknum+sys1.rootblocknum);i<sys1.sysblocknum;i++) if(fat1[i]==0)flag++;if(flag==0){ printf("磁盘已满");return 2;}if((l+n-fil[p->fdtblockindex].filelen)>flag*BlockSize)return 3;for(i=(sys1.fatblocknum+sys1.resblocknum+sys1.rootblocknum);i<sys1.sysblocknum;i++) {if(fat1[i]==0){k++;if(k>=n3){fat1[m]=i+1;fat1[i]=-1;break;}elsefat1[m]=i+1;m=i;} }}flag=0;k=0;n3=(l+n)/BlockSize+((l+n)%BlockSize?1:0);j=(l/BlockSize)+(l%BlockSize?1:0); /*求文件指针所在文件的相对块号*/st2=(char *)malloc((n3-j+1)*BlockSize);if(l==0)j=1;num=fil[p->fdtblockindex].firstblockaddr;for(i=1;i<j;i++)num=fat1[num-1];if(!l%BlockSize) /*写第1块*/{fseek(fp,(num-1)*BlockSize+l-(i-1)*BlockSize,0);fread(st2,BlockSize,1,fp);for(c=0;c<n;c++)st2[c]=ptr[c];fseek(fp,(num-1)*BlockSize+l-(i-1)*BlockSize,0);fwrite(st2,BlockSize,1,fp);num=fat1[num-1];fflush(fp);}else{ fseek(fp,(num-1)*BlockSize,0);fread(st2,BlockSize,1,fp);for(c=0;c<n;c++)st2[c+l-(j-1)*BlockSize]=ptr[c];fseek(fp,(num-1)*BlockSize,0);fwrite(st2,BlockSize,1,fp);num=fat1[num-1];fflush(fp);}for(i=1;i<(n3-j);i++) /*写第2块-倒数第2块*/ { fseek(fp,(num-1)*BlockSize,0);fwrite(st2+i*BlockSize,BlockSize,1,fp);num=fat1[num-1];fflush(fp);}if((n3-j)>0) /*写最后一块*/{fseek(fp,(num-1)*BlockSize,0);fread(st2+i*BlockSize,BlockSize,1,fp);for(c=0;c<(n-((j*BlockSize-l)+(i-1)*BlockSize));c++)st2[c+i*BlockSize]=ptr[c+(j*BlockSize-l)+(i-1)*BlockSize];fseek(fp,(num-1)*BlockSize,0);fwrite(st2+i*BlockSize,BlockSize,1,fp);fflush(fp);}p->filepos=l+n; /*修改文件指针*/if((n+l)>fil[p->fdtblockindex].filelen)fil[p->fdtblockindex].filelen=n+l; /*修改文件长度*/return 0;}int FEOF(int fileid) /*判断文件是否结束*/{int flag;struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)if(p->filepos>=fil[p->fdtblockindex].filelen)return 0;elsereturn 1;}return 2;}long FGETPOS(int fileid){struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid)return (p->filepos);elsep=p->next;}printf("get faile!\n");return(-1);}int FSETPOS(int fileid, long offset) /*设置文件指针*/ {struct FCBBlock *p;p=fcb;while(p){if(p->fileid==fileid){if(offset>fil[p->fdtblockindex].filelen||offset<0)return 1;else{p->filepos=offset;return 0;}}p=p->next;}printf("get faile!\n");return(2);}void DISPLAY(){printf("\t\t---------------欢迎使用FAT文件系统---------------\n");printf("\t\t------------------制作人:王兴宙------------------\n\n");printf("\t\t-------------------------------------------------\n");printf("\t\t\t\t 请输入您要选择的功能:\n\n");printf("\t\t\t\t 开始运行文件系统:start\n");printf("\t\t\t\t 建立文件:creat\n");printf("\t\t\t\t 显示文件目录:list\n");printf("\t\t\t\t 删除文件:del\n");printf("\t\t\t\t 打开文件:open\n");printf("\t\t\t\t 关闭文件:close\n");printf("\t\t\t\t 文件块读:read\n");printf("\t\t\t\t 文件块写:write\n");printf("\t\t\t\t 设置文件指针:set\n");printf("\t\t\t\t 获取文件指针:getp\n");printf("\t\t\t\t 获取文件长度:getl\n");printf("\t\t\t\t 退出文件系统:exit\n");printf("\t\t---------------------------------------------------\n");}void test(char *filename) /*测试函数*/{char *t,cmd[10],fname[12];struct FCBBlock *p;int flag,len,id,flag1=0,l;while(1){DISPLAY();scanf("%s",cmd);if(!strcmp(cmd,"start")) /*开始运行系统命令*/ {fp=OPENSYS(filename);printf("成功打开文件系统\n");while(1){scanf("%s",cmd);if(!strcmp(cmd,"creat")) /*创建文件*/ {printf("请输入文件名:");scanf("%s",fname);flag=FCREATE(fname);if(flag==0)printf("文件创建成功!\n");if(flag==1)printf("文件名太长!\n");if(flag==2)printf(" 磁盘已满!\n");if(flag==3)printf("文件已经存在!\n");}else if(!strcmp(cmd,"list")) /*显示文件目录*/ LISTDIR();else if(!strcmp(cmd,"del")) /*删除文件*/ {scanf("%s",fname);flag=FDELETE(fname);if(flag==0)printf("成功删除文件!\n");if(flag==1)printf("文件被打开,要删除文件请先关闭文件!\n"); }else if(!strcmp(cmd,"open")) /*打开文件*/ {scanf("%s",fname);flag=FOPEN(fname);if(flag==0)printf("文件没有被发现,不能打开!\n");elseprintf("成功打开,文件ID是:%d\n",flag);}else if(!strcmp(cmd,"close")) /*关闭文件*/ {scanf("%s",fname);flag=FCLOSE(fname);if(flag==1)printf("成功关闭文件!\n");}else if(!strcmp(cmd,"read")) /*读文件*/ {scanf("%d",&id);p=fcb;printf("请输入读文件大小:");scanf("%d",&len);flag=FREAD(str,len,id);if(flag==1)printf("文件没有被打开,请先打开文件!\n");if(flag==2)printf("读取文件失败\n");}else if(!strcmp(cmd,"write")) /*写文件*/ { scanf("%d",&id);printf("请输入写文件大小:");scanf("%d",&len);ptr=(char *)malloc(len+1);printf("请输入内容:");scanf("%s",ptr);flag=FWRITE(ptr,len,id);if(flag==1)printf("文件没有被打开,请先打开文件!\n");if(flag==1)printf("wu kong jian!\n");if(flag==3)printf("写操作失败!\n");if(flag==0)printf("成功写文件!\n");}elseif(!strcmp(cmd,"set")) /*设置文件指针*/{scanf("%d",&id);printf("输入指针:");scanf("%d",&l);flag=FSETPOS(id,l);if(flag==0)printf("成功设置指针!\n");if(flag==1)printf("指针太长或错误!\n");if(flag==2)printf("这个文件没有打开!\n");}else if(!strcmp(cmd,"getp")) /*获取文件指针*/ {scanf("%d",&id);flag=FGETPOS(id);if(flag!=-1)printf("pos is:%d\n",flag);if(flag==-1)printf("这个文件不能打开!\n");}elseif(!strcmp(cmd,"getl")) /*获取文件长度*/{scanf("%s",fname);flag=FGETLEN(fname);if(flag==-1)printf("这个文件不能被发现!\n");elseprintf("文件长度:%d\n",flag);}else if(!strcmp(cmd,"exit")) /*关闭文件系统*/ {flag=CLOSESYS(fp);if(flag==0)printf("成功关闭文件管理系统!\n");break;}elseprintf("这条命令错误!\n");}}elseprintf("这条命令错误!\n");}}int main(){ struct ReserveBlock sys;char filename[]="fatsys.dat";int *fat;int i,j;system("graftabl 936");clrscr();fcb=NULL;memset(&sys,255,BlockSize); /*磁盘格式化*/printf("请输入文件系统块的数目(5~32767):");scanf("%d",&(sys.sysblocknum));sys.resblocknum=1;sys.fatblocknum=sys.sysblocknum/(BlockSize/sizeof(int))+((sys.sysblocknum%(BlockSize/sizeof(int)))?1:0);fat=(int*)malloc(BlockSize*sys.fatblocknum);memset(fat,255,BlockSize*sys.fatblocknum);memset(fat,0,sizeof(int)*sys.sysblocknum);sys.rootblocknum=RootSize;j=sys.resblocknum+sys.fatblocknum+sys.rootblocknum;for (i=0;i<j;i++)fat[i]=-1;memset(&fillchar,0,BlockSize);fp=fopen(filename,"w+b");fwrite(&sys,1,BlockSize,fp);for (i=0;i<sys.fatblocknum;i++)fwrite(fat+i*BlockSize/sizeof(int),1,BlockSize,fp);j=sys.resblocknum+sys.fatblocknum;for(i=0;i<(sys.sysblocknum-j);i++)fwrite(&fillchar,1,BlockSize,fp);fclose(fp);free(fat);test(filename);return 0;}模拟实现单级目录、单级索引的索引文件系统一、课程设计的性质和目的操作系统课程设计是计算机专业的专业课程,通过课程设计使学生进一步巩固课堂所学知识,全面熟悉、掌握操作系统的基本设计方法和技巧,进一步提高分析问题、解决问题及上机操作能力,为将来从事计算机工作打下一定的专业基础。

相关文档
最新文档