910 likes | 1.24k Views
第 4 讲 文件操作. 张玉宏 电子科技大学计算机学院. 什么是文件系统?. 大容量 直接存取 的 磁盘存储器 以及 顺序存取 的 磁带存储器 等的出现,为程序和数据等软件资源的透明存取提供了物质基础,这导致了对软件资源管理质的飞跃 —— 文件系统 的出现。. 几个误区. 首先,需要澄清对于文件系统的一些错误理解: 经常有这样的说法, “ 我的硬盘是 FAT32 格式的 ” , “ C 盘是 NTFS 格式 ” 等,它们的错误在于, NTFS 或是 FAT32 并不是 硬盘格式 ,而是 管理文件的系统格式
E N D
第4讲 文件操作 张玉宏 电子科技大学计算机学院
什么是文件系统? • 大容量直接存取的磁盘存储器以及顺序存取的磁带存储器等的出现,为程序和数据等软件资源的透明存取提供了物质基础,这导致了对软件资源管理质的飞跃——文件系统的出现。
几个误区 • 首先,需要澄清对于文件系统的一些错误理解: • 经常有这样的说法,“我的硬盘是FAT32格式的”,“C盘是NTFS格式”等,它们的错误在于,NTFS或是FAT32并不是硬盘格式,而是管理文件的系统格式 • 其次刚买回来的硬盘并没有文件系统,必须使用FDISK或Windows 2000/XP的分区工具等对其进行分区并格式化后才会有管理文件的系统,因此文件系统是对应分区的,而不是硬盘,不管是将硬盘分成一个分区,还是几个分区。
什么是文件系统? • 举个通俗的比喻,一块硬盘就像一个块空地,文件就像不同的材料,我们首先得根据自己的目的在空地上建起不同的仓库(分区) • 并且指定好(格式化)每个仓库对材料的管理规范(文件系统),这样才能将材料运进仓库保管。 • 所以一个磁盘可以有多个逻辑分区,也就可以对应多个文件系统。
什么是文件系统? • 文件本身不会受所在分区的文件系统影响,就像同样是汽车轮胎在A仓库可能直接堆在地上,而B仓库则会挂在墙上,仅仅是放置和管理方法不同而已 • 因此,在NTFS分区和FAT32分区的文件可以随意在分区间移动,内容不会因此产生任何不同。
什么是文件系统? • 文件系统把相应的程序和数据看作文件,并把它们存放在磁盘或磁带等大容量存储介质上,从而做到对程序和数据的透明存取。 • 这里,透明存取是指不必了解文件存放的物理结构和查找方法等与存取介质有关的部分,只需给定一个代表某段程序或数据的文件名,文件系统就会自动地完成对与给定文件名相对应文件的有关操作。
什么是文件系统 • 操作系统中与管理文件有关的软件和数据称为文件系统。 • 它负责为用户建立文件,撤消、读写、修改和复制文件,还负责完成对文件的按名存取和进行存取控制。
Widows的主流文件系统 • FAT(File Allocation Table)是“文件分配表”的意 思。对我们来说,它的意义在于对硬盘分区的管理。 • FAT16、FAT32、NTFS是目前最常见的三种文件系统。
Widows的主流文件系统 • FAT16:我们以前用的DOS、Windows 95都使用FAT16文件系统 • 现在常用的Windows 98/2000/XP等系统均支持FAT16文件系统。它最大可以管理大到2GB的分区,但每个分区最多只能有65525个簇(簇是磁盘空间的配置单位)。 • 随着硬盘或分区容量的增大,每个簇所占的空间将越来越大,从而导致硬盘空间的浪费。
Widows的主流文件系统 • FAT32:随着大容量硬盘的出现,从Windows 98开始,FAT32开始流行。它是FAT16的增强版本,可以支持大到2TB(2048GB)的分区。 • FAT32使用的簇比FAT16小,从而有效地节约了硬盘空间。
Widows的主流文件系统 • NTFS (英文全称为“NT File System) :微软Windows NT内核的系列操作系统支持的、一个特别为网络和磁盘配额、文件加密等管理安全特性设计的磁盘格式。 • 随着以NT为内核的Windows 2000/XP的普及,很多个人用户开始用到了NTFS。 • NTFS也是以簇为单位来存储数据文件,但NTFS中簇的大小并不依赖于磁盘或分区的大小。 • 簇尺寸的缩小不但降低了磁盘空间的浪费,还减少了产生磁盘碎片的可能。NTFS支持文件加密管理功能,可为用户提供更高层次的安全保证。
Widows的主流文件系统 • 只有Windows NT/2000/XP才能识别NTFS系统,Windows 9x/Me以及DOS等操作系统都不能支持、识别NTFS格式的磁盘。 • 由于DOS系统不支持NTFS系统,所以最好不要将C:盘制作为NTFS系统,这样在系统崩溃后便于在DOS系统下修复。 • 而且这种情况下,如果不知道C盘是NTFS格式,在DOS下进行对C盘格式化操作,那么格式化的不是C盘而是D盘!!!。
其它文件系统 • FAT12:是IBM第一台个人电脑中的MS-DOS 1.0使用的文件系统,主要用于软盘。这种系统限制分区的容量最大为16MB——但这根本算不上问题,因为软盘容量从来没有达到16MB。 ISO9660:CD-ROM的文件系统,不过现在已经延伸出很多新的文件系统,对它的一些缺点进行了弥补,如Juliet等。 UDF:可读写光盘的文件系统。 Mac HFS:苹果电脑的文件系统,对大容量磁盘有比较好的支持。不过,现在大多数苹果电脑还在使用FAT32文件系统。
Linux的操作系统的主流文件系统 • linux操作系统的磁盘分区格式与其他操作系统完全不同,至少需要两个专门的分区: • 一种是linux native主分区 • 一种是linux swap交换分区。这两种分区格式的安全性与稳定性极佳,结合linux操作系统后,死机的机会大大减少。 • 但是,目前支持这一分区格式的操作系统只有linux
Linux的操作系统的主流文件系统 • SWAP分区是LINUX暂时存储数据的交换分区,它主要是把主内存上暂时不用得数据存起来,在需要的时候再调进内存内 • Linux Native是存放系统文件的地方,能用EXT2, EXT3等分区类型,
Linux的操作系统的主流文件系统 • 还可以创建哪些分区(仅列常用几种)。 /boot分区,它包含了操作系统的内核和在启动系统过程中所要用到的文件,建这个分区是有必要的。这个分区的大小约在50MB―100MB之间。 • /usr分区,是Red Hat Linux系统存放软件的地方,如有可能应将最大空间分给它。 /home分区,是用户的home目录所在地,这个分区的大小取决于有多少用户。
Linux的操作系统的主流文件系统 • /var/log分区,是系统日志记录分区,如果设立了这一单独的分区,这样即使系统的日志文件出现了问题,它们也不会影响到操作系统的主分区。 • /tmp分区,用来存放临时文件。这对于多用户系统或者网络服务器来说是有必要的。这样即使程序运行时生成大量的临时文件,或者用户对系统进行了错误的操作,文件系统的其它部分仍然是安全的。因为文件系统的这一部分仍然还承受着读写操作,所以它通常会比其它的部分更快地发生问题。 • /bin分区,存放标准系统实用程序。 • /dev分区,存放设备文件。 • /opt分区,存放可选的安装的软件。 • /sbin分区,存放标准系统管理文件。 上面介绍了几个常用的分区,一般来说我们需要一个SWAP分区,一个/boot分区,一个/usr分区,一个/home 分区,一个/var/log分区。当然这没有什么规定,完全是依照你个人来定的。
Linux主流文件系统 • 在Linux系统中,每个分区都是一个文件系统,都有自己的目录层次结构。 • Linux的最重要特征之一就是支持多种文件系统,这样它更加灵活,并可以和许多其它种操作系统共存。 • Virtual File System(虚拟文件系统)使得Linux可以支持多个不同的文件系统。由于系统已将Linux文件系统的所有细节进行了转换,所以Linux核心的其它部分及系统中运行的程序将看到统一的文件系统。 • Linux的虚拟文件系统允许用户同时能透明地安装许多不同的文件系统。虚拟文件系统是为Linux用户提供快速且高效的文件访问服务而设计的。
Linux支持的文件系统 Linux采用虚拟文件系统技术,可支持多种常见的文件系统,并允许用户在不同的磁盘分区上安装不同的文件系统。
Linux支持的文件系统类型主要有: msdos:MS-DOS采用的FAT文件系统 • Vfat:Windows中通用的文件系统 • sysV:UNIX中最常用的system V文件系统 • nfs:网络文件系统 • iso9660:CD-ROM的标准文件系统
ext • ext是第一个专门为开发的Linux的文件系统类型,叫做扩展文件系统。 • 它是1992年4月完成的,对Linux早期的发展产生了重要作用。但是,由于其在稳定性、速度和兼容性上存在许多缺陷,现在已经很少使用了。
ext2 • ext2是为解决ext文件系统的缺陷而设计的可扩展的、高性能的文件系统,它又被称为二级扩展文件系统。 • ext2是1993年发布的,设计者是Rey Card。 • ext2可以支持256字节的长文件名,其单一文件大小和文件系统本身的容量上限与文件系统本身的簇大小有关。 • 2000年以前几乎所有的Linux发行版都使用ext2作为默认的文件系统。
ext3 • ext3被设计成是ext2的升级版本,尽可能方便用户从ext2向ext3迁移。 • 和ext2相比,ext3提供了更佳的安全性,这就是数据日志和元数据日志之间的不同。 • ext3是一种日志式文件系统,日志式文件系统的优越性在于由于文件系统都有快取层参与运作,如不使用时必须将文件系统卸下,以便将快取层的资料写回磁盘中。
JFS • JFS是一种提供日志的字节级文件系统。该文件系统主要是为满足服务器(从单处理器系统到高级多处理器和群集系统)的高吞吐量和可靠性需求而设计、开发的。 • JFS文件系统是为面向事务的高性能系统而开发的。
ReiserFS • ReiserFS的第一次公开亮相是在1997年7月23日,Hans Reiser把他的基于平衡树结构的ReiserFS文件系统在网上公布。 • ReiserFS被看作是一个更加激进和现代的文件系统。
ReiserFS • ReiserFS 使用了特殊的、优化的平衡树来组织所有的文件系统数据,这为其自身提供了非常不错的性能改进,也能够减轻文件系统设计上的人为约束。 • ReiserFS一个最受批评的缺点是,每升级一个版本都将要将磁盘重新格式化一次,而且它的安全性能和稳定性与ext3相比有一定的差距。
Linux支持多种文件系统 • Linux支持多种文件系统,如ext、ext2、minix、iso9660、msdos、fat、vfat、nfs等。 • 在这些具体文件系统的上层,Linux提供了虚拟文件系统(VFS)来统一它们的行为,虚拟文件系统为不同的文件系统与内核的通信提供了一致的接口。 • 下图给出了Linux中文件系统的关系:
C语言对文件的操作--概述 • 在程序运行时,程序本身和数据一般都存放在内存中。当程序运行结束后,存放在内存中的数据被释放。 • 如果需要长期保存程序运行所需的原始数据,或程序运行产生的结果,就必须以文件形式存储到外部存储介质上。 • 这就涉及到文件的操作
两类函数 • 在Linux平台下对文件编程可以使用两类函数: • (1)Linux操作系统文件API; • (2)C语言I/O库函数。 • 前者依赖于Linux系统调用 • 后者实际上与操作系统是独立的,因为在任何操作系统下,使用C语言I/O库函数操作文件的方法都是相同的。 • 本章将对这两种方法进行实例讲解。
Linux的文件描述符和流 • 文件描述符和流 • 文件描述符是打开或创建文件时Linux内核分配的一个非负整数,用来跟踪打开的文件。 • 有3个文件描述符有特定意义:0-标准输入,1-标准输出,2-标准错误 • 在POSIX标准中定义了3个常量来表示这3个文件描述符:STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO。要使用这些常量,必须包含头文件<unistd.h>
Linux的文件描述符和流 • 流是标准C语言I/O库提出来的概念,隐藏了文件描述符,以更抽象的概念代替。 • 用标准I/O库函数打开或创建文件时,返回一个FILE结构的指针,该结构包含了文件描述符、缓冲区地址、缓冲区大小等信息。 • 有3个预定义的流于3个预定义的文件描述符对应:stdin,stdout,stderr,要使用这3个流必须包含头文件<stdio.h>
2.Linux文件API • Linux的文件操作API涉及到创建、打开、读写和关闭文件 • 2.1创建 • int creat(const char *filename, mode_t mode); • 参数mode指定新建文件的存取权限,它同umask一起决定文件的最终权限(mode&umask),其中umask代表了文件在创建时需要去掉的一些存取权限。
系统调用umask() • umask可通过系统调用umask()来改变: • int umask(int newmask); • 该调用将umask设置为newmask,然后返回旧的umask,它只影响读、写和执行权限。
2.2打开文件 • int open(const char *pathname, int flags); • int open(const char *pathname, int flags, mode_t mode); • open函数有两个形式,其中pathname是我们要打开的文件名(包含路径名称,缺省是认为在当前路径下面),flags可以去下面的一个值或者是几个值的组合:
如果使用了O_CREATE标志,则使用的函数是 • int open(const char *pathname,int flags,mode_t mode); • 这个时候我们还要指定mode标志,用来表示文件的访问权限。 • mode可以是以下情况的组合:
Mode的标志位 • 除了可以通过上述宏进行“或”逻辑产生标志以外, • 也可以自己用数字来表示: • Linux总共用5个数字来表示文件的各种权限:第一位表示设置用户ID;第二位表示设置组ID;第三位表示用户自己的权限位;第四位表示组的权限;最后一位表示其他人的权限。
Mode的标志位 • 每个数字可以取1(执行权限)、2(写权限)、4(读权限)、0(无)或者是这些值的和。例如,要创建一个用户可读、可写、可执行,但是组没有权限,其他人可以读、可以执行的文件,并设置用户ID位。 • 那么,应该使用的模式是1(设置用户ID)、0(不设置组ID)、7(1+2+4,读、写、执行)、0(没有权限)、5(1+4,读、执行)即10705:
open("test", O_CREAT, 10705); 上述语句等价于 • open("test", O_CREAT, S_ISUID |S_IRWXU | S_IROTH | S_IXOTH); • 如果文件打开成功,open函数会返回一个文件描述符,以后对该文件的所有操作就可以通过对这个文件描述符进行操作来实现。
注意: • 以O_CREAT为标志的open实际上实现了文件创建的功能,因此,下面的函数等同creat()函数: • int open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
2.3 读写 • 在文件打开以后(打开文件才能创建一个文件描述符),我们才可对文件进行读写了,Linux中提供文件读写的系统调用是read、write函数: • int read(int fd, const void *buf, size_t length); • int write(int fd, const void *buf, size_t length);
2.3 读写 • 其中参数buf为指向缓冲区的指针,length为缓冲区的大小(以字节为单位)。 • 函数read()实现从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中,返回值为实际读取的字节数。 • 函数write实现将把length个字节从buf指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为实际写入的字节数。 • 当然文件的读写指针也随之移动!!!
2.4 定位 • 对于随机文件,我们可以随机的指定位置读写,使用如下函数进行定位: • int lseek(int fd, offset_t offset, int whence); • lseek()将文件读写指针相对whence移动offset个字节。操作成功时,返回文件指针相对于文件头的位置。参数whence可使用下述值 • SEEK_SET:相对文件开头SEEK_CUR:相对文件读写指针的当前位置SEEK_END:相对文件末尾
2.4 定位 • offset可取负值,例如下述调用可将文件指针相对当前位置向前移动5个字节: • lseek(fd, -5, SEEK_CUR); • 由于lseek函数的返回值为文件指针相对于文件头的位置,因此下列调用的返回值就是文件的长度: • lseek(fd, 0, SEEK_END);
2.5 关闭文件 • 当我们操作完成以后,我们要关闭文件了,只要调用close就可以了,其中fd是我们要关闭的文件描述符: • int close(int fd);
实例编程 • 例程:编写一个程序,在当前目录下创建用户可读写文件“hello.txt”,在其中写入“Hello, Chengdu College of UESTC”,关闭该文件。再次打开该文件,读取其中的内容并输出在屏幕上。