简单文件系统|操作系统中文件系统是指什么

❶ 如何实现一个文件系统

摘要:本文目的是分析在linux系统中如何实现新的文件系统。在介绍文件系统具体实现前先介绍文件系统的概念和作用,抽象出了文件系统概念模型。熟悉文件系统的内涵后,我们再近一步讨论Linux系统中和文件系统的特殊风格和具体文件系统在Linux中组成结构,为读者勾画出Linux中文件系统工作的全景图。最后,我们再通过Linux中最简单的Romfs作实例分析实现文件系统的普遍步骤。(我们假定读者已经对Linux文件系统初步了解)什么是文件系统首先要谈的概念就是什么是文件系统,它的作用到底是什么。文件系统的概念虽然许多人都认为是再清晰不过的了,但其实我们往往在谈论中或多或少地夸大或片缩小了它的实际概念(至少我时常混淆),或者说,有时借用了其它概念,有时说的又不够全面。比如在操作系统中,文件系统这个术语往往既被用来描述磁盘中的物理布局,比如有时我们说磁盘中的“文件系统”是EXT2或说把磁盘格式化成FAT32格式的“文件系统”等——这时所说的“文件系统”是指磁盘数据的物理布局格式;另外,文件系统也被用来描述内核中的逻辑文件结构,比如有时说的“文件系统”的接口或内核支持Ext2等“文件系统”——这时所说的文件系统都是内存中的数据组织结构而并非磁盘物理布局。还有些时候说“文件系统”负责管理用户读写文件——这时所说的“文件系统”往往描述操作系统中的“文件管理系统”,也就是文件子系统。虽然上面我们列举了混用文件系统的概念的几种情形,但是却也不能说上述说法就是错误的,因为文件系统概念本身就囊括众多概念,几乎可以说在操作系统中自内存管理、系统调度到I/O系统、设备驱动等各个部分都和文件系统联系密切,有些部分和文件系统甚至未必能明确划分——所以不能只知道文件系统是系统中数据的存储结构,一定要全面认识文件系统在操作系统中的角色,才能具备自己开发新文件系统的能力。为了澄清文件系统的概念,必须先来看看文件系统在操作系统中处于何种角色,分析文件系统概念的内含外延。所以我们先抛开Linux文件系统的实例,而来看看操作系统中文件系统的普遍体系结构,从而增强对文件系统的理论认识。下面以软件组成的结构图[1]的方式描述文件系统所涉及的内容。 我们针对各层做以简要分析:首先我们来分析最低层——设备驱动层,该层负责与外设——磁盘等——通讯。基于磁盘的文件系统都需要和存储设备打交道,而系统操作外设离不开驱动程序。所以内核对文件的最后操作行为就是调用设备驱动程序完成从主存(内存)到辅存(磁盘)的数据传输。文件系统相关的多数设备都属于块设备,常见的块设备驱动程序有磁盘驱动,光驱驱动等,之所以称它们为块设备,一个原因是它们读写数据都是成块进行的,但是更重要的原因是它们管理的数据能够被随机访问——不需要向字符设备那样必须顺序访问。设备驱动层的上一层是物理I/O层,该层主要作为计算机外部环境和系统的接口,负责系统和磁盘交换数据块。它要知道据块在磁盘中存储位置,也要知道文件数据块在内存缓冲中的位置,另外它不需要了解数据或文件的具体结构。可以看到这层最主要的工作是标识别磁盘扇区和内存缓冲块[2]之间的映射关系。再上层是基础I/O监督层,该层主要负责选择文件 I/O需要的设备,调度磁盘请求等工作,另外分配I/O缓冲和磁盘空间也在该层完成。由于块设备需要随机访问数据,而且对速度响应要求较高,所以操作系统不能向对字符设备那样简单、直接地发送读写请求,而必须对读写请求重新优化排序,以能节省磁盘寻址时间,另外也必须对请求提交采取异步调度(尤其写操作)的方式进行。总而言之,内核对必须管理块设备请求,而这项工作正是由该层负责的。倒数第二层是逻辑I/O层,该层允许用户和应用程序访问记录。它提供了通用的记录(record)I/O操作,同时还维护基本文件数据。由于为了方便用户操作和管理文件内容,文件内容往往被组织成记录形式,所以操作系统为操作文件记录提供了一个通用逻辑操作层。和用户最靠近的是访问方法层,该层提供了一个从用户空间到文件系统的标准接口,不同的访问方法反映了不同的文件结构,也反映了不同的访问数据和处理数据方法。这一层我们可以简单地理解为文件系统给用户提供的访问接口——不同的文件格式(如顺序存储格式、索引存储格式、索引顺序存储格式和哈希存储格式等)对应不同的文件访问方法。该层要负责将用户对文件结构的操作转化为对记录的操作。对比上面的层次图我们再来分析一下数据流的处理过程,加深对文件系统的理解。假如用户或应用程序操作文件(创建/删除),首先需要通过文件系统给用户空间提供的访问方法层进入文件系统,接着由使用逻辑I/O层对记录进行给定操作,然后记录将被转化为文件块,等待和磁盘交互。这里有两点需要考虑——第一,磁盘管理(包括再磁盘空闲区分配文件和组织空闲区);第二,调度块I/O请求——这些由基础I/O监督层的工作。再下来文件块被物理I/O层传递给磁盘驱动程序,最后磁盘驱动程序真正把数据写入具体的扇区。至此文件操作完毕。当然上面介绍的层次结构是理想情况下的理论抽象,实际文件系统并非一定要按照上面的层次或结构组织,它们往往简化或合并了某些层的功能(比如Linux文件系统因为所有文件都被看作字节流,所以不存在记录,也就没有必要实现逻辑I/O层,进而也不需要在记录相关的处理)。但是大体上都需要经过类似处理。如果从处理对象上和系统独立性上划分,文件系统体系结构可以被分为两大部分:——文件管理部分和操作系统I/O部分。文件管理系统负责操作内存中文件对象,并按文件的逻辑格式将对文件对象的操作转化成对文件块的操作;而操作系统I/O部分负责内存中的块与物理磁盘中的数据交换。数据表现形式再文件操作过程中也经历了几种变化:在用户访问文件系统看到的是字节序列,而在字节序列被写入磁盘时看到的是内存中文件块(在缓冲中),在最后将数据写入磁盘扇区时看到的是磁盘数据块[3]。本文所说的实现文件系统主要针对最开始讲到第二种情况——内核中的逻辑文件结构(但其它相关的文件管理系统和文件系统磁盘存储格式也必须了解),我们用数据处理流图来分析一下逻辑文件系统主要功能和在操作系统中所处的地位。 其中文件系统接口与物理布局管理是逻辑文件系统要负责的主要功能。文件系统接口为用户提供对文件系统的操作,比如open、close、read、write和访问控制等,同时也负责处理文件的逻辑结构。物理存储布局管理,如同虚拟内存地址转化为物理内存地址时,必须处理段页结构一样,逻辑文件结构必须转化到物理磁盘中,所以也要处理物理分区和扇区的实际存储位置,分配磁盘空间和内存中的缓冲也要在这里被处理。所以说要实现文件系统就必须提供上面提到的两种功能,缺一不可。在了解了文件系统的功能后,我们针对Linux操作系统分析具体文件系统如何工作,进而掌握实现一个文件系统需要的步骤。Linux 文件系统组成结构Linux 文件系统的结构除了我们上面所提到的概念结构外,最主要有两个特点,一个是文件系统抽象出了一个通用文件表示层——虚拟文件系统或称做VFS。另外一个重要特点是它的文件系统支持动态安装(或说挂载、登陆等),大多数文件系统都可以作为根文件系统的叶子接点被挂在到根文件目录树下的子目录上。另外Linux系统在文件读写的I/O操作上也采取了一些先进技术和策略。我们先从虚拟文件系统入手分析linux文件系统的特性,然后介绍有关文件系统的安装、注册和读写等概念。虚拟文件系统虚拟文件系统为用户空间程序提供了文件系统接口。系统中所有文件系统不但依赖VFS共存,而且也依靠VFS系统协同工作。通过虚拟文件系统我们可以利用标准的UNIX文件系统调用对不同介质上的不同文件系统进行读写操作[4]。虚拟文件系统的目的是为了屏蔽各种各样不同文件系统的相异操作形式,使得异构的文件系统可以在统一的形式下,以标准化的方法访问、操作。实现虚拟文件系统利用的主要思想是引入一个通用文件模型——该模型抽象出了文件系统的所有基本操作(该通用模型源于Unix风格的文件系统),比如读、写操作等。同时实际文件系统如果希望利用虚拟文件系统,既被虚拟文件系统支持,也必须将自身的诸如,“打开文件”、“读写文件”等操作行为以及“什么是文件”,“什么是目录”等概念“修饰”成虚拟文件系统所要求的(定义的)形式,这样才能够被虚拟文件系统支持和使用。我们可以借用面向对象的一些思想来理解虚拟文件系统,虚拟文件系统好比一个抽象类或接口,它定义(但不实现)了文件系统最常见的操作行为。而具体文件系统好比是具体类,它们是特定文件系统的实例。具体文件系统和虚拟文件系统的关系类似具体类继承抽象类或实现接口。而在用户看到或操作的都是抽象类或接口,但实际行为却发生在具体文件系统实例上。至于如何将对虚拟文件系统的操作转化到对具体文件系统的实例,就要通过注册具体文件系统到系统,然后再安装具体文件系统才能实现转化,这点可以想象成面向对象中的多态概念。我们个实举例来说明具体文件系统如何通过虚拟文件系统协同工作。例如:假设一个用户输入以下shell命令:$ cp /hda/test1 /removable/test2其中 /removable是MS-DOS磁盘的一个安装点,而 /hda 是一个标准的第二扩展文件系统( Ext2)的目录。cp命令不用了解test1或test2的具体文件系统,它所看到和操作的对象是VFS。cp首先要从ext3文件系统读出test1文件,然后写入MS-DOS文件系统中的test2。VFS会将找到ext3文件系统实例的读方法,对test1文件进行读取操作;然后找到MS-DOS(在Linux中称VFAT)文件系统实例的写方法,对test2文件进行写入操作。可以看到 VFS是读写操作的统一界面,只要具体文件系统符合VFS所要求的接口,那么就可以毫无障碍地透明通讯了。 Unix风格的文件系统虚拟文件系统的通用模型源于Unix风格的文件系统,所谓Unix风格是指Unix传统上文件系统传统上使用了四种和文件系统相关的抽象概念:文件(file)、目录项(dentry)、索引节点(inode)和安装点(mount point)。文件——在Unix中的文件都被看做是一有序字节串,它们都有一个方便用户或系统识别的名称。另外典型的文件操作有读、写、创建和删除等。目录项——不要和目录概念搞混淆,在Linux中目录被看作文件。而目录项是文件路径中的一部分。一个文件路径的例子是“/home/wolfman/foo”——根目录是/,目录home,wolfman和文件foo都是目录项。索引节点——Unix系统将文件的相关信息(如访问控制权限、大小、拥有者、创建时间等等信息),有时被称作文件的元数据(也就是说,数据的数据)被存储在一个单独的数据结构中,该结构被称为索引节点(inode)。安装点——在Unix中,文件系统被安装在一个特定的安装点上,所有的已安装文件系统都作为根文件系统树中的叶子出现在系统中。上述概念是Unix文件系统的逻辑数据结构,但相应的Unix文件系统(Ext2等)磁盘布局也实现了部分上述概念,比如文件信息(文件数据元)存储在磁盘块中的索引节点上。当文件被载如内存时,内核需要使用磁盘块中的索引点来装配内存中的索引接点。类似行为还有超级块信息等。对于非Unix风格文件系统,如FAT或NTFS,要想能被VFS支持,它们的文件系统代码必须提供这些概念的虚拟形式。比如,即使一个文件系统不支持索引节点,它也必须在内存中装配起索引节点结构体——如同本身固有一样。或者,如果一个文件系统将目录看作是一种特殊对象,那么要想使用VFS,必须将目录重新表示为文件形式。通常,这种转换需要在使用现场引入一些特殊处理,使得非Unix文件系统能够兼容Unix文件系统的使用规则和满足VFS的需求。通过这些处理,非Unix文件系统便可以和VFS一同工作了,是性能上多少会受一些影响[5]。这点很重要,我们实现自己文件系统时必须提供(模拟)Unix风格文件系统的抽象概念。Linux文件系统中使用的对象Linux文件系统的对象就是指一些数据结构体,之所以称它们是对象,是因为这些数据结构体不但包含了相关属性而且还包含了操作自身结构的函数指针,这种将数据和方法进行封装的思想和面向对象中对象概念一致,所以这里我们就称它们是对象。Linux文件系统使用大量对象,我们简要分析以下VFS相关的对象,和除此还有和进程相关的一些其它对象。VFS相关对象这里我们不展开讨论每个对象,仅仅是为了内容完整性,做作简要说明。VFS中包含有四个主要的对象类型,它们分别是:超级块对象,它代表特定的已安装文件系统。索引节点对象,它代表特定文件。目录项对象,它代表特定的目录项。文件对象,它代表和进程打开的文件。每个主要对象中都包含一个操作对象,这些操作对象描述了内核针对主要对象可以使用的方法。最主要的几种操作对象如下:super_operations对象,其中包括内核针对特定文件系统所能调用的方法,比如read_inode()和sync_fs()方法等。inode_operations对象,其中包括内核针对特定文件所能调用的方法,比如create()和link()方法等。dentry_operations对象,其中包括内核针对特定目录所能调用的方法,比如d_compare()和d_delete()方法等。file对象,其中包括,进程针对已打开文件所能调用的方法,比如read()和write()方法等。除了上述的四个主要对象外,VFS还包含了许多对象,比如每个注册文件系统都是由file_system_type对象表示——描述了文件系统及其能力(如比如ext3或XFS);另外每一个安装点也都利用vfsmount对象表示——包含了关于安装点的信息,如位置和安装标志等。其它VFS对象系统上的每一进程都有自己的打开文件,根文件系统,当前工作目录,安装点等等。另外还有几个数据结构体将VFS层和文件的进程紧密联系,它们分别是:file_struct 和fs_structfile_struct结构体由进程描述符中的files项指向。所有包含进程的信息和它的文件描述符都包含在其中。第二个和进程相关的结构体是fs_struct。该结构由进程描述符的fs项指向。它包含文件系统和进程相关的信息。每种结构体的详细信息不在这里说明了。缓存对象除了上述一些结构外,为了缩短文件操作响应时间,提高系统性能,Linux系统采用了许多缓存对象,例如目录缓存、页面缓存和缓冲缓存(已经归入了页面缓存),这里我们对缓存做简单介绍。页高速缓存(cache)是 Linux内核实现的一种主要磁盘缓存。其目的是减少磁盘的I/O操作,具体的讲是通过把磁盘中的数据缓存到物理内存中去,把对磁盘的I/O操作变为对物理内存的I/O操作。页高速缓存是由RAM中的物理页组成的,缓存中每一页都对应着磁盘中的多个块。每当内核开始执行一个页I/O操作时(通常是对普通文件中页大小的块进行磁盘操作),首先会检查需要的数据是否在高速缓存中,如果在,那么内核就直接使用高速缓存中的数据,从而避免了访问磁盘。但我们知道文件系统只能以每次访问数个块的形式进行操作。内核执行所有磁盘操作都必须根据块进行,一个块包含一个或多个磁盘扇区。为此,内核提供了一个专门结构来管理缓冲buffer_head。缓冲头[6]的目的是描述磁盘扇区和物理缓冲之间的映射关系和做I/O操作的容器。但是缓冲结构并非独立存在,而是被包含在页高速缓存中,而且一个页高速缓存可以包含多个缓冲。我们将在文件后面的文件读写部分看到数据如何被从磁盘扇区读入页高速缓存中的缓冲中的。文件系统的注册和安装使用文件系统前必须对文件系统进行注册和安装,下面分别对这两种行为做简要介绍。文件系统的注册VFS要想能将自己定义的接口映射到实际文件系统的专用方法上,必须能够让内核识别实际的文件系统,实际文件系统通过将代表自身属性的文件类型对象(file_system_type)注册(通过register_filesystem()函数)到内核,也就是挂到内核中的文件系统类型链表上,来达到使文件系统能被内核识别的目的。反过来内核也正是通过这条链表来跟踪系统所支持的各种文件系统的。我们简要分析一下注册步骤:struct file_system_type {const char *name; /*文件系统的名字*/int fs_flags; /*文件系统类型标志*//*下面的函数用来从磁盘中读取超级块*/struct super_block * (*read_super) (struct file_system_type *, int,const char *, void *);struct file_system_type * next; /*链表中下一个文件系统类型*/struct list_head fs_supers; /*超级块对象链表*/};其中最重要的一项是read_super()函数,它用来从磁盘上读取超级块,并且当文件系统被装载时,在内存中组装超级块对象。要实现一个文件系统首先需要实现的结构体便是file_system_type结构体。注册文件系统只能保证文件系统能被系统识别,但此刻文件系统尚不能使用,因为它还没有被安装到特定的安装点上。所以在使用文件系统前必须将文件系统安装到安装点上。文件系统被实际安装时,将在安装点创建一个vfsmount结构体。该结构体用代表文件系统的实例——换句话说,代表一个安装点。vfsmount结构被定义在<linux/mount.h>中,下面是具体结构―――――――――――――――――――――――――――――――――――――――struct vfsmount{struct list_head mnt_hash; /*哈希表*/struct vfsmount *mnt_parent; /*父文件系统*/struct dentry *mnt_mountpoint; /*安装点的目录项对象*/struct dentry *mnt_root; /*该文件系统的根目录项对象*/struct super_block *mnt_sb; /*该文件系统的超级块*/struct list_head mnt_mounts; /*子文件系统链表*/struct list_head mnt_child; /*和父文件系统相关的子文件系统*/atomic_t mnt_count; /*使用计数*/int mnt_flags; /*安装标志*/char *mnt_devname; /*设备文件名字*/struct list_head mnt_list; /*描述符链表*/};――――――――――――――――――――――――――――――――――――――文件系统如果仅仅注册,那么还不能被用户使用。要想使用它还必须将文件系统安装到特定的安装点后才能工作。下面我们接着介绍文件系统的安装[7]过程。安装过程用户在用户空间调用mount()命令——指定安装点、安装的设备、安装类型等——安装指定文件系统到指定目录。mount()系统调用在内核中的实现函数为sys_mount(),该函数调用的主要例程是do_mount(),它会取得安装点的目录项对象,然后调用do_add_mount()例程。do_add_mount()函数主要做的是首先使用do_kern_mount()函数创建一个安装点,再使用graft_tree()将安装点作为叶子与根目录树挂接起来。整个安装过程中最核心的函数就是do_kern_mount()了,为了创建一个新安装点(vfsmount),该函数需要做一下几件事情:l 1 检查安装设备的权利,只有root权限才有能力执行该操作。l 2 Get_fs_type()在文件链表中取得相应文件系统类型(注册时被填加到练表中)。l 3 Alloc_vfsmnt()调用slab分配器为vfsmount结构体分配存储空间,并把它的地址存放在mnt局部变量中。l 4 初始化mnt->mnt_devname域l 5 分配新的超级块并初始化它。do_kern_mount( )检查file_system_type描述符中的标志以决定如何进行如下操作:根据文件系统的标志位,选择相应的方法读取超级块(比如对Ext2,romfs这类文件系统调用get_sb_dev();对于这种没有实际设备的虚拟文件系统如 ramfs调用get_sb_nodev())——读取超级块最终要使用文件系统类型中的read_super方法。安装过程做的最主要工作是创建安装点对象,挂接给定文件系统到根文件系统的指定接点下,然后初始化超级快对象,从而获得文件系统基本信息和相关操作方法(比如读取系统中某个inode的方法)。总而言之,注册过程是告之内核给定文件系统存在于系统内;而安装是请求内核对给定文件系统进行支持,使文件系统真正可用。转载

❷ 磁盘文件系统的文件系统大家族

常用的文件系统有很多,MS-DOS和Windows 3.x使用FAT16文件系统,默认情况下Windows 98也使用FAT16,Windows 98和Me可以同时支持FAT16、FAT32两种文件系统,Windows NT则支持FAT16、NTFS两种文件系统,Windows 2000可以支持FAT16、FAT32、NTFS三种文件系统,Linux则可以支持多种文件系统,如FAT16、FAT32、NTFS、Minix、ext、ext2、xiafs、HPFS、VFAT等,不过Linux一般都使用ext2文件系统。下面,笔者就简要介绍这些文件系统的有关情况:(1)FAT16FAT的全称是“File Allocation Table(文件分配表系统)”,最早于1982年开始应用于MS-DOS中。FAT文件系统主要的优点就是它可以允许多种操作系统访问,如MS-DOS、Windows 3.x、Windows 9x、Windows NT和OS/2等。这一文件系统在使用时遵循8.3命名规则(即文件名最多为8个字符,扩展名为3个字符)。磁盘文件系统文件系统就是在硬盘上存储信息的格式。在所有的计算机系统中,都存在一个相应的文件系统,它规定了计算机对文件和文件夹进行操作处理的各种标准和机制。因此,用户对所有的文件和文件夹的操作都是通过文件系统来完成的。其中Windows 2000支持的文件系统包括:o 标准文件分配表( FAT ),运行Windows NT、Windows 95、MS – DOS或OS/2可以存取主分区或者逻辑分区FAT上的文件。o 增强的文件分配表(FAT32),这是在大型磁盘驱动器(超过512 兆字节)上存储文件的极有效的系统,如果用户的驱动器使用了这种格式,则会在驱动器上创建多至几百兆的额外硬盘空间,从而更高效地存储数据。此外,可使程序运行加快50 %,而使用的计算机系统资源却更少。o Windows 2000中推荐的文件系统(NTFS),只有运行Windows 2000或Windows NT的计算机才可以存取NTFS卷中的文件。用户在安装Windows 2000 之前,应该先决定选择哪一种文件系统。Windows 2000支持使用NTFS文件系统和文件分配表文件系统(FAT或FAT32)。本节以下内容将对以上的几种文件系统作简单介绍。FAT文件系统FAT文件系统最初用于小型磁盘和简单文件结构的简单文件系统。FAT文件系统得名于它的组织方法:放置在卷起始位置的文件分配表。为了保护卷,使用了两份拷贝,确保即使损坏了一份也能正常工作。另外,为确保正确装卸启动系统所必须的文件,文件分配表和根文件夹必须存放在固定的位置。采用FAT文件系统格式化的卷以簇的形式进行分配。默认的簇大小由卷的大小决定。对于FAT文件系统,簇数目必须可以用16位的二进制数字表示,并且是2的乘方。通过使用命令行提示符下的format程序,用户可以指定簇的大小。不过,用户所指定的簇的大小必须大于表中给出的大小。由于额外开销的原因,在大于511MB的卷中不推荐使用FAT文件系统。如果用户的计算机上运行的是Windows 95、Windows for Workgroups、MS-DOS、OS/2或Windows 95以前的版本,那么FAT文件系统格式是最佳的选择。不过,需要注意的是,FAT文件系统最好被用在较小的卷上。因为,在不考虑簇大小的情况下,使用FAT文件系统,卷不能大于4GB。FAT32文件系统FAT32文件系统提供了比FAT文件系统更为先进的文件管理特性,例如,支持超过32GB的卷以及通过使用更小的簇来更有效率地使用磁盘空间。作为FAT文件系统的增强版本,它可以在容量从512MB到2TB的磁盘驱动器上使用。在以前的操作系统中,只有Windows 2000、Windows 98和Windows 95 OEM Release 2版能够访问FAT32卷。MS-DOS、Windows 3.1及较早的版本、Windows for Workgroups、Windows NT 4.0及更早的版本都不能识别FAT32卷,同时也不能从FAT32上启动它们。FAT和FAT32可以与Windows 2000之外的其它操作系统兼容。如果设置了双重启动配置,很可能需要FAT或FAT32文件系统。如果用户正在对Windows 2000 和另一个操作系统进行双重启动配置,请选择一个适用于后者的文件系统。选择的标准如下:o 如果安装分区小于2GB,或者如果希望双重启动配置Windows 2000 和MS – DOS、Windows 3.1、Windows 95或Windows NT较早的版本,将安装分区格式化为FAT。o 在大于或等于2GB的分区上使用FAT32文件系统。如果在Windows 2000安装程序中选择使用FAT格式化,并且安装分区大于2GB,安装程序将自动按FAT32格式化。对于大于32GB的分区,建议您使用NTFS而不用FAT32文件系统。NTFS文件系统Windows 2000所推荐使用的NTFS文件系统提供了FAT和FAT32文件系统所没有的、全面的性能,可靠性和兼容性。NTFS文件系统的设计目标就是用来在很大的硬盘上能够很快地执行诸如:读、写和搜索这样的标准文件操作,甚至包括像文件系统恢复这样的高级操作。NTFS文件系统包括了公司环境中文件服务器和高端个人计算机所需的安全特性。NTFS文件系统还支持对于关键数据完整性十分重要的数据访问控制和私有权限。除了可以赋予Windows 2000计算机中的共享文件夹特定权限外, NTFS文件和文件夹无论共享与否都可以赋予权限。NTFS是Windows 2000 中唯一允许为单个文件指定权限的文件系统。然而,当用户从NTFS卷移动或复制文件到FAT卷时,NTFS文件系统权限和其它特有属性将会丢失。像FAT文件系统一样,NTFS文件系统使用簇作为磁盘分配的基本单元。在NTFS文件系统中,默认的簇大小取决于卷的大小。在磁盘管理器中,用户可以指定的簇大小最大为4k。Windows 2000包括一个新版本的NTFS,该文件系统在原有的灵活的安全特性(比如域和用户帐户数据库)之上又加入了新的特性,如活动目录(Active Directory)Windows 2000中使用的NTFS文件系统支持以下特性:o 活动目录。使网络管理者和网络用户可以方便灵活地查看和控制网络资源。o 域。它是活动目录的一部分,帮助网络管理者兼顾管理的简单性和网络的安全性。例如,只有在NTFS文件系统中用户才能设置单个文件的许可权限而不仅仅是目录的许可权限。o 文件加密。能够大大提高信息的安全性。o 稀松文件。应用程序生成的一种特殊文件,它的文件尺寸非常大,但实际上只需要少部分的磁盘空间。就是说,NTFS只需要给这种文件实际写入的数据分配磁盘存储空间。o 其他的数据存储模式。这些模式可以提高存储和修改信息的效率。o 磁盘活动的恢复日志。它将帮助用户在电源失效或其他系统故障时快速恢复信息。o 磁盘配额。管理者可以管理和控制每个用户所能使用的最大磁盘空间。o 对于大容量驱动器的良好扩展性。NTFS中最大驱动器的尺寸远远大于FAT格式的,而且,NTFS的性能和存储效率并不象FAT那样随着驱动器尺寸的增大而降低。只有在NTFS文件系统中用户才可以使用诸如活动目录和基于域的安全策略等重要特性。需要把整个磁盘或某个磁盘驱动器做成NTFS文件系统的用户,可在安装Windows 2000时,在安装向导的帮助下完成所有操作。安装程序可以很轻松地把分区转化为新版本的NTFS文件系统,即使以前的分区使用的是FAT或FAT32。安装程序会检测现有的文件系统格式。如果是NTFS,则自动进行转换;如果是FAT或FAT32,会提示安装者是否转换为NTFS。用户也可以在安装完毕之后使用Convert.exe来把FAT或FAT32的分区转化为新版本的NTFS分区。无论是在运行安装程序中还是在运行安装程序之后,这种转换都不会使用户的文件受到损害(相对于重新格式化磁盘来说)。如果使用双重启动配置,则可能无法从计算机上的另一个操作系统访问NTFS分区上的文件。所以,如果要使用双重启动配置,FAT32或者FAT文件系统将是更适合的选择。NTFS和文件分配表文件系统的区别运行Windows 2000的计算机的磁盘分区可以使用三种类型的文件系统: NTFS、FAT和FAT32。安装Windows 2000的用户建议使用NTFS文件系统。FAT和FAT32很相似,只是FAT32更适合于较大容量的硬盘(对于大硬盘来说,最佳的文件系统是NTFS)。本节将帮助用户比较各种文件系统的优劣。NTFS文件系统是使用Windows 2000 所推荐的文件系统。NTFS具有FAT文件系统的所有基本功能,并且提供如下的FAT或FAT32文件系统所没有的优点:o 更为安全的文件。o 更好的磁盘压缩性能。o 支持最大达2TB的大硬盘(NTFS可支持的最大磁盘容量比FAT的大得多,而且随着磁盘容量的增大,NTFS的性能不像FAT那样随之降低)。o 双重启动配置(在同一台计算机上同时安装有Windows 2000和其他操作系统)。只有一种情况用户可能需要使用FAT或FAT32文件系统,就是确有必要配置Windows 2000和早期操作系统的双重启动。在这种情况下,用户就应该把系统配置成双重启动并在硬盘上用FAT或FAT32分区做为主分区(启动分区)。这是因为早期的操作系统不能访问采用最新版本NTFS格式的本地硬盘分区,唯一的例外就是Windows NT 4.0 加上Service Pack 4或更高版本,它能够访问这种硬盘分区,但也有所限制。Windows NT不能访问使用NTFS新特性存储的本地文件,因为这些NTFS新特性在Windows NT4.0发布时还没有出现。如果服务器不需要配置双重启动功能,建议文件系统采用NTFS格式。Windows 2000支持由Windows 95或Windows 98创建的任何尺寸的FAT32卷。然而,Windows 2000只能格式化最大32GB的FAT32卷。如果用户在安装过程中选择的FAT分区大于2GB,则安装程序自动地把它格式化为FAT32格式。对于大于32GB的卷建议使用NTFS而不是FAT32。VFATVFAT是“扩展文件分配表系统”的意思,主要应用于在Windows 95中。它对FAT16文件系统进行扩展,并提供支持长文件名,文件名可长达255个字符,VFAT仍保留有扩展名,而且支持文件日期和时间属性,为每个文件保留了文件创建日期/时间、文件最近被修改的日期/时间和文件最近被打开的日期/时间这三个日期/时间HPFS高性能文件系统。OS/2的高性能文件系统(HPFS)主要克服了FAT文件系统不适合于高档操作系统这一缺点,HPFS支持长文件名,比FAT文件系统有更强的纠错能力。Windows NT也支持HPFS,使得从OS/2到Windows NT的过渡更为容易。HPFS和NTFS有包括长文件名在内的许多相同特性,但使用可靠性较差。ext2这是Linux中使用最多的一种文件系统,因为它是专门为Linux设计,拥有最快的速度和最小的CPU占用率。ext2既可以用于标准的块设备(如硬盘),也被应用在软盘等移动存储设备上。现在已经有新一代的Linux文件系统如SGI公司的XFS、ReiserFS、ext3文件系统等出现。

❸ 目前有几种文件系统,比较好用的

ntfsNTFS 提供长文件名、数据保护和恢复,并通过目录和文件许可实现安全性。版NTFS 支持大硬盘和在权多个硬盘上存储文件(称为卷)。例如,一个大公司的数据库可能大得必须跨越不同的硬盘。NTFS 提供内置安全性特征,它控制文件的隶属关系和访问。从DOS或其他操作系统上不能直接访问 NTFS 分区上的文件。如果要在DOS下读写NTFS分区文件的话可以借助第三方软件;现如今,Linux系统上已可以使用 NTFS-3G进行对 NTFS 分区的完美读写,不必担心数据丢失

❹ 操作系统中文件系统是指什么

1)简单的说文件系统就是指系统允许存放的文件所在的那个磁盘空间的格式。文件系统有很多,版如:权ntfs、fat32、ext3、ext2、swap、nfs等2)硬链接简单的说就是一个指针,指向的是文件索引节点,系统并不为它重新分配inode。由于不同的文件系统的inode分配方式是不同的,所以如果跨文件系统,那这个硬连接就会出错的

❺ 为linux系统设计一个简单的二级文件系统。要求做到以下几点:

#include<stdio.h> #include<string.h> #include<stdlib.h> #define MEM_D_SIZE 1024*1024 //总磁盘空间为1M#define DISKSIZE 1024//磁盘块的大小1K#define DISK_NUM 1024//磁盘块数目1K#define FATSIZE DISK_NUM*sizeof(struct fatitem)//FAT表大小#define ROOT_DISK_NO FATSIZE/DISKSIZE+1//根目录起始盘块号#define ROOT_DISK_SIZE sizeof(struct direct)//根目录大小#define DIR_MAXSIZE 1024//路径最大长度为1KB#define MSD 5//最大子目录数5#define MOFN 5//最大文件深度为5#define MAX_WRITE 1024*128//最大写入文字长度128KB struct fatitem /* size 8*/ { int item; /*存放文件下一个磁盘的指针*/ char em_disk; /*磁盘块是否空闲标志位 0 空闲*/ }; struct direct { /*—–文件控制快信息—–*/ struct FCB { char name[9]; /*文件/目录名 8位*/ char property; /*属性 1位目录 0位普通文件*/ int size; /*文件/目录字节数、盘块数)*/ int firstdisk; /*文件/目录 起始盘块号*/ int next; /*子目录起始盘块号*/ int sign; /*1是根目录 0不是根目录*/ }directitem[MSD+2]; }; struct opentable { struct openttableitem { char name[9]; /*文件名*/ int firstdisk; /*起始盘块号*/ int size; /*文件的大小*/ }openitem[MOFN]; int cur_size; /*当前打文件的数目*/ }; struct fatitem *fat; /*FAT表*/ struct direct *root; /*根目录*/ struct direct *cur_dir; /*当前目录*/ struct opentable u_opentable; /*文件打开表*/ int fd=-1; /*文件打开表的序号*/ char *bufferdir; /*记录当前路径的名称*/ char *fdisk; /*虚拟磁盘起始地址*/ void initfile(); void format(); void enter(); void halt(); int create(char *name); int open(char *name); int close(char *name); int write(int fd,char *buf,int len); int read(int fd,char *buf); int del(char *name); int mkdir(char *name); int rmdir(char *name); void dir(); int cd(char *name); void print(); void show(); void initfile() { fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请 1M空间*/ format(); } void format() { int i; FILE *fp; fat = (struct fatitem *)(fdisk+DISKSIZE); /*计算FAT表地址,引导区向后偏移 1k)*/ /*—–初始化FAT表————*/ fat[0].item=-1; /*引导块*/ fat[0].em_disk='1'; for(i=1;i<ROOT_DISK_NO-1;i++) /*存放 FAT表的磁盘块号*/ { fat[i].item=i+1; fat[i].em_disk='1'; } fat[ROOT_DISK_NO].item=-1; /*存放根目录的磁盘块号*/ fat[ROOT_DISK_NO].em_disk='1'; for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++) { fat[i].item = -1; fat[i].em_disk = '0'; } /*———————————————–*/ root = (struct direct *)(fdisk+DISKSIZE+FATSIZE); /*根目录的地址*/ /*初始化目录*/ /*———指向当前目录的目录项———*/ root->directitem[0].sign = 1; root->directitem[0].firstdisk = ROOT_DISK_NO; strcpy(root->directitem[0].name,"."); root->directitem[0].next = root->directitem[0].firstdisk; root->directitem[0].property = '1'; root->directitem[0].size = ROOT_DISK_SIZE; /*——-指向上一级目录的目录项———*/ root->directitem[1].sign = 1; root->directitem[1].firstdisk = ROOT_DISK_NO; strcpy(root->directitem[1].name,".."); root->directitem[1].next = root->directitem[0].firstdisk; root->directitem[1].property = '1'; root->directitem[1].size = ROOT_DISK_SIZE; if((fp = fopen("disk.dat","wb"))==NULL) { printf("Error:\n Cannot open file \n"); return; } for(i=2;i<MSD+2;i++) /*-子目录初始化为空-*/ { root->directitem[i].sign = 0; root->directitem[i].firstdisk = -1; strcpy(root->directitem[i].name,""); root->directitem[i].next = -1; root->directitem[i].property = '0'; root->directitem[i].size = 0; } if((fp = fopen("disk.dat","wb"))==NULL) { printf("Error:\n Cannot open file \n"); return; } if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1) /*把虚拟磁盘空间保存到磁盘文件中*/ { printf("Error:\n File write error! \n"); } fclose(fp); } void enter() { FILE *fp; int i; fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char)); /*申请 1M空间*/ if((fp=fopen("disk.dat","rb"))==NULL) { printf("Error:\nCannot open file\n"); return; } if(!fread(fdisk,MEM_D_SIZE,1,fp)) /*把磁盘文件disk.dat 读入虚拟磁盘空间(内存)*/ { printf("Error:\nCannot read file\n"); exit(0); } fat = (struct fatitem *)(fdisk+DISKSIZE); /*找到FAT表地址*/ root = (struct direct *)(fdisk+DISKSIZE+FATSIZE);/*找到根目录地址*/ fclose(fp); /*————–初始化用户打开表——————*/ for(i=0;i<MOFN;i++) { strcpy(u_opentable.openitem[i].name,""); u_opentable.openitem[i].firstdisk = -1; u_opentable.openitem[i].size = 0; } u_opentable.cur_size = 0; cur_dir = root; /*当前目录为根目录*/ bufferdir = (char *)malloc(DIR_MAXSIZE*sizeof(char)); strcpy(bufferdir,"Root:"); }void halt() { FILE *fp; int i; if((fp=fopen("disk.dat","wb"))==NULL) { printf("Error:\nCannot open file\n"); return; } if(!fwrite(fdisk,MEM_D_SIZE,1,fp)) /*把虚拟磁盘空间(内存)内容读入磁盘文件disk.dat */ { printf("Error:\nFile write error!\n"); } fclose(fp); free(fdisk); free(bufferdir); return;}int create(char *name) { int i,j; if(strlen(name)>8) /*文件名大于 8位*/ return(-1); for(j=2;j<MSD+2;j++) /*检查创建文件是否与已存在的文件重名*/ { if(!strcmp(cur_dir->directitem[j].name,name)) break; } if(j<MSD+2) /*文件已经存在*/ return(-4); for(i=2;i<MSD+2;i++) /*找到第一个空闲子目录*/ { if(cur_dir->directitem[i].firstdisk==-1) break; } if(i>=MSD+2) /*无空目录项*/ return(-2); if(u_opentable.cur_size>=MOFN) /*打开文件太多*/ return(-3); for(j=ROOT_DISK_NO+1;j<DISK_NUM;j++) /*找到空闲盘块 j 后退出*/ { if(fat[j].em_disk=='0') break; } if(j>=DISK_NUM) return(-5); fat[j].em_disk = '1'; /*将空闲块置为已经分配*/ /*———–填写目录项—————–*/ strcpy(cur_dir->directitem[i].name,name); cur_dir->directitem[i].firstdisk = j; cur_dir->directitem[i].size = 0; cur_dir->directitem[i].next = j; cur_dir->directitem[i].property = '0'; /*———————————*/ fd = open(name); return 0; } int open(char *name) { int i, j; for(i=2;i<MSD+2;i++) /*文件是否存在*/ { if(!strcmp(cur_dir->directitem[i].name,name)) break; } if(i>=MSD+2) return(-1); /*——–是文件还是目录———————–*/ if(cur_dir->directitem[i].property=='1')return(-4); /*——–文件是否打开———————–*/ for(j=0;j<MOFN;j++) { if(!strcmp(u_opentable.openitem[j].name,name)) break; } if(j<MOFN) /*文件已经打开*/ return(-2); if(u_opentable.cur_size>=MOFN) /*文件打开太多*/ return(-3); /*——–查找一个空闲用户打开表项———————–*/ for(j=0;j<MOFN;j++) { if(u_opentable.openitem[j].firstdisk==-1) break; } /*————–填写表项的相关信息————————*/ u_opentable.openitem[j].firstdisk = cur_dir->directitem[i].firstdisk; strcpy(u_opentable.openitem[j].name,name); u_opentable.openitem[j].size = cur_dir->directitem[i].size; u_opentable.cur_size++; /*———-返回用户打开表表项的序号————————–*/ return(j); } int close(char *name) { int i; for(i=0;i<MOFN;i++) { if(!strcmp(u_opentable.openitem[i].name,name)) break; } if(i>=MOFN) return(-1); /*———–清空该文件的用户打开表项的内容———————*/ strcpy(u_opentable.openitem[i].name,""); u_opentable.openitem[i].firstdisk = -1; u_opentable.openitem[i].size = 0; u_opentable.cur_size–; return 0; } int write(int fd, char *buf, int len) { char *first; int item, i, j, k; int ilen1, ilen2, modlen, temp; /*———-用 $ 字符作为空格 # 字符作为换行符———————–*/ char Space = 32; char Endter= '\n'; for(i=0;i<len;i++) { if(buf[i] == '$') buf[i] = Space; else if(buf[i] == '#') buf[i] = Endter; } /*———-读取用户打开表对应表项第一个盘块号———————–*/ item = u_opentable.openitem[fd].firstdisk; /*————-找到当前目录所对应表项的序号————————-*/ for(i=2;i<MSD+2;i++) { if(cur_dir->directitem[i].firstdisk==item) break; } temp = i; /*-存放当前目录项的下标-*/ /*——找到的item 是该文件的最后一块磁盘块——————-*/ while(fat[item].item!=-1) { item =fat[item].item; /*-查找该文件的下一盘块–*/ } /*—–计算出该文件的最末地址——-*/ first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE; /*—–如果最后磁盘块剩余的大小大于要写入的文件的大小——-*/ if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len) { strcpy(first,buf); u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len; cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len; } else { for(i=0;i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++) {/*写一部分内容到最后一块磁盘块的剩余空间(字节)*/ first[i] = buf [i]; } /*—–计算分配完最后一块磁盘的剩余空间(字节) 还剩下多少字节未存储——-*/ ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE); ilen2 = ilen1/DISKSIZE; modlen = ilen1%DISKSIZE; if(modlen>0) ilen2 = ilen2+1; /*–还需要多少块磁盘块-*/ for(j=0;j<ilen2;j++) { for(i=ROOT_DISK_NO+1;i<DISK_NUM;i++)/*寻找空闲磁盘块*/ { if(fat[i].em_disk=='0') break; } if(i>=DISK_NUM) /*–如果磁盘块已经分配完了-*/ return(-1); first = fdisk+i*DISKSIZE; /*–找到的那块空闲磁盘块的起始地址-*/ if(j==ilen2-1) /*–如果是最后要分配的一块-*/ { for(k=0;k<len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE)-j*DISKSIZE;k++) first[k] = buf[k]; } else/*-如果不是要最后分配的一块–*/ { for(k=0;k<DISKSIZE;k++) first[k] =buf[k]; } fat[item].item = i; /*–找到一块后将它的序号存放在上一块的指针中-*/ fat[i].em_disk = '1'; /*–置找到的磁盘快的空闲标志位为已分配-*/ fat[i].item = -1; /*–它的指针为 -1 (即没有下一块)-*/ } /*–修改长度-*/ u_opentable.openitem[fd].size = u_opentable.openitem[fd].size+len; cur_dir->directitem[temp].size = cur_dir->directitem[temp].size+len; } return 0; } int read(int fd, char *buf) { int len = u_opentable.openitem[fd].size; char *first; int i, j, item; int ilen1, modlen; item = u_opentable.openitem[fd].firstdisk; ilen1 = len/DISKSIZE; modlen = len%DISKSIZE; if(modlen!=0) ilen1 = ilen1+1; /*–计算文件所占磁盘的块数-*/ first = fdisk+item*DISKSIZE; /*–计算文件的起始位置-*/ for(i=0;i<ilen1;i++) { if(i==ilen1-1) /*–如果在最后一个磁盘块-*/ { for(j=0;j<len-i*DISKSIZE;j++) buf[i*DISKSIZE+j] = first[j]; } else /*–不在最后一块磁盘块-*/ { for(j=0;j<len-i*DISKSIZE;j++) buf[i*DISKSIZE+j] = first[j]; item = fat[item].item; /*-查找下一盘块-*/ first = fdisk+item*DISKSIZE; } } return 0; } int del(char *name) { int i,cur_item,item,temp; for(i=2;i<MSD+2;i++) /*–查找要删除文件是否在当前目录中-*/ { if(!strcmp(cur_dir->directitem[i].name,name)) break; }

❻ 文件系统是如何建立的

右击,新建文件夹针对各层简要分析如下:1.首先我们来分析最低层——设备驱动层,该层负责与外设——磁盘等——通讯。文件系统都需要和存储设备打交道,而系统操作外设时离不开驱动程序。所以内核对文件的最后操作行为就是调用设备驱动程序完成从主存(内存)到辅存(磁盘)的数据传输。文件系统相关的多数设备都属于块设备,常见的块设备驱动程序有磁盘驱动,光驱驱动等,之所以称它们为块设备,一个原因是它们读写数据都是成块进行的,但是更重要的原因是它们管理的数据能够被随机访问——不需要像字符设备那样必须顺序访问。2.设备驱动层的上一层是物理I/O层,该层主要作为计算机外部环境和系统的接口,负责系统和磁盘之间数据块的交换。它要知道数据块在磁盘中地存储位置,也要知道文件数据块在内存缓冲中的位置,另外,它不需要了解数据或文件的具体结构。可以看到,这层最主要的工作是识别磁盘扇区和内存缓冲块[2]之间的映射关系。3.再上层是基础I/O监督层,该层主要负责选择文件 I/O需要的设备,调度磁盘请求等工作,另外分配I/O缓冲和磁盘空间也在该层完成。由于块设备需要随机访问数据,而且对速度响应要求较高,所以操作系统不能像对字符设备那样简单、直接地发送读写请求,而必须对读写请求重新优化排序,以能节省磁盘寻址时间,另外也必须对请求提交采取异步调度(尤其写操作)的方式进行。总而言之,内核必须管理块设备请求,而这项工作正是由该层负责的。4.倒数第二层是逻辑I/O层,该层允许用户和应用程序访问记录。它提供了通用的记录(record)I/O操作,同时还维护基本文件数据。为了方便用户操作和管理文件内容,文件内容往往被组织成记录形式,所以操作系统为操作文件记录提供了一个通用的逻辑操作层。

❼ 什么是文件系统常见的文件系统有哪些

文件系统是操作系统用于明确磁盘或分来区上的文件的方法和数据结构;即回在磁盘上组织答文件的方法。也指用于存储文件的磁盘或分区,或文件系统种类。操作系统中负责管理和存储文件源信息的软件机构称为文件管理系统,简称文件系统。文件系统由三部分组成:与文件管理有关软件、被管理文件以及实施文件管理所需数据结构。从系统角度来看,百文件系统是对文件存储器空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用度户不再使用时撤销文件等。

❽ 常用的文件系统有哪些(如FAT32)它们有什么区别

fat和fat32的区别,1.fat32文件系统的优点:与fat相比,fat仅能处理容量小于2gb的驱动器,而fat32可以创建任意容量的单一驱动器。fat32存储文件更有效,可使硬盘容纳的内容更多fat16与fat32的区别主要在于簇的大小不同,但还有几处其他的不同。fat32可以精细的分配每一单元,还可以在根目录增加更多的条目。简单介绍一下fat32的优越性,fat32比fat16可以更有效地分配磁盘的空间。fat32卷的根文件夹是一个普通的簇链,所以可将其定位在卷的任何地方,因此fat32可以支持根多的条目数量,fat16只能有512个。由于fat32比fat16使用了更小的簇,所以可以创建高大32gb的卷

❾ 什么是文件系统都有哪些

文件系统是操作系统用于明确磁盘或分区上的文件的方法和数据结构;即在磁盘上组织文件的方法。也指用于存储文件的磁盘或分区,或文件系统种类。因此,可以说"我有2个文件系统"意思是他有2个分区,一个存文件,或他用 "扩展文件系统",意思是文件系统的种类。 磁盘或分区和它所包括的文件系统的不同是很重要的。少数程序(包括最有理由的产生文件系统的程序)直接对磁盘或分区的原始扇区进行操作;这可能破坏一个存在的文件系统。大部分程序基于文件系统进行操作,在不同种文件系统上不能工作。 一个分区或磁盘能作为文件系统使用前,需要初始化,并将记录数据结构写到磁盘上。这个过程就叫建立文件系统。 大部分UNIX文件系统种类具有类似的通用结构,即使细节有些变化。其中心概念是超级块superblock, i节点inode, 数据块data block,目录块directory block, 和间接块indirection block。超级块包括文件系统的总体信息,比如大小(其准确信息依赖文件系统)。 i节点包括除了名字外的一个文件的所有信息,名字与i节点数目一起存在目录中,目录条目包括文件名和文件的i节点数目。 i节点包括几个数据块的数目,用于存储文件的数据。 i节点中只有少量数据块数的空间,如果需要更多,会动态分配指向数据块的指针空间。这些动态分配的块是间接块;为了找到数据块,这名字指出它必须先找到间接块的号码。 UNIX文件系统通常允许在文件中产生孔(hole) (用lseek ; 请看手册), 意思是文件系统假装文件中有一个特殊的位置只有0字节,但没有为这文件的这个位置保留实际的磁盘空间(这意味着这个文件将少用一些磁盘空间)。这对小的二进制文件经常发生,Linux共享库、一些数据库和其他一些特殊情况。 (孔由存储在间接块或i节点中的作为数据块地址的一个特殊值实现,这个特殊地址说明没有为文件的这个部分分配数据块,即,文件中有一个孔。) 孔有一定的用处。在笔者的系统中,一个简单的测量工具显示在200MB使用的磁盘空间中,由于孔,节约了大约4MB。在这个系统中,程序相对较少,没有数据库文件。有关这个测量工具的细节请看附录 A.

❿ 常用的文件系统类型有哪些

常见的文件系统有FAT、NTFS、ExtFAT、ext2、ext3、reiserFS、VFAT、APFS。

1、FAT文件系统。

FAT文件系统诞生于1977年,它最初是为软盘设计的文件系统,但是后来随着微软推出dos和win 9x系统,FAT文件系统经过适配被逐渐用到了硬盘上,并且在那时的20年中,一直是主流的文件系统。

2、NTFS文件系统。

它是一种比FAT32功能更加强大的文件系统,从windows 2000之后的windows系统的默认文件系统都是NTFS,而且这些windows系统只能够安装在NTFS格式的磁盘上。NTFS系统是一个日志性的文件系统,系统中对文件的操作都可以被记录下来,当系统崩溃之后,利用日志功能可以修复数据。

3、ExtFAT文件系统。

ExFAT也是微软开发的文件系统,它是专门为闪存盘设计的文件系统,单个文件突破了4G的限制,而且分区的最大容量可达64ZB,建议512TB。 ExFAT在windows,Linux以及Mac系统上,都可以读写,作为U盘或者是移动硬盘的格式还是比较合适的。

4、ext2文件系统。

ext2是为解决ext文件系统的缺陷而设计的可扩展的、高性能的文件系统,又被称为二级扩展文件系统。它是Linux文件系统中使用最多的类型,并且在速度和CPU利用率上较为突出。ext2存取文件的性能极好,并可以支持256字节的长文件名,是GNU/Linux系统中标准的文件系统。

5、ext3文件系统。

ext3是ext2文件系统的日志版本,它在ext2文件系统中增加了日志的功能。ext3提供了3种日志模式:日志(journal)、顺序(ordered)和回写(writeback)。与ext2相比,ext3提供了更好的安全性以及向上向下的兼容性能。

6、reiserFS文件系统。

reiserFS是Linux环境下最稳定的日志文件系统之一,使用快速的平衡二叉树(binary tree)算法来查找磁盘上的自由空间和已有的文件,其搜索速度高于ext2,reiserFS能够像其他大多数文件系统一样,可动态的分配索引节,而无须在文件系统中创建固定的索引节。

7、VFAT文件系统。

VFAT主要用于处理长文件的一种文件名系统,它运行在保护模式下并使用VCACHE进行缓存,并具有和Windows系列文件系统和Linux文件系统兼容的特性。因此VFAT可以作为Windows和Linux交换文件的分区。

8、APFS文件系统。

APFS是苹果公司发布的新的文件格式,替代目前所使用的HFS+格式。这一全新文件系统专门针对闪存/SSD进行优化,提供了更强大的加密、写入时复制元数据、空间分享、文件和目录克隆、快照、目录大小快速调整、原子级安全存储基元,以及改进的文件系统底层技术。


赞 (0)