LINUX环境高级编程-第二讲文件_第1页
LINUX环境高级编程-第二讲文件_第2页
LINUX环境高级编程-第二讲文件_第3页
LINUX环境高级编程-第二讲文件_第4页
LINUX环境高级编程-第二讲文件_第5页
已阅读5页,还剩250页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux环境高级编程第二讲

文件的操作第二讲

文件的操作文件I/O(第三章)文件和目录(第四章)第二讲

文件的操作文件I/O(第三章)文件和目录(第四章)文件I/O文件的基本操作(打开、定位、读写、关闭)I/O效率文件共享其他重要I/O函数文件I/O文件的基本操作(打开、定位、读写、关闭)I/O效率文件共享其他重要I/O函数文件操作基本顺序打开 open创建

creat定位

lseek读 read写 write关闭 closeopen函数用于打开或者创建一个文件函数原型#include<fcntl.h>int

open(constchar*pathname,int

oflag,...)参数第一个参数pathname:要打开或者创建的文件名第二个参数oflag:用于指定文件打开模式、标志等信息。open函数第二个参数oflag:Linux头文件已经为文件打开模式、标志等定义了若干的宏oflag需要指定这些宏宏定义在/usr/include/bits/fcntl.h中在该头文件中,只读打开标志被定义为:#defineO_RDONLY 00open函数oflag:文件打开模式标志

以下三个标志必须指定一个且只能指定一个O_RDONLY : 只读打开O_WRONLY : 只写打开O_RDWR : 读写打开其他文件标志

下面的标志是可以选择的,可通过C语言的或运算与文件打开标志进行组合open函数oflag其他文件标志:

O_APPEND:每次写的数据都添加到文件尾

O_TRUNC:若此文件存在,并以读写或只写打开,则文件长度为0

O_CREAT:若文件不存在,则创建该文件。此时,open函数需要第三个参数,用于指定该文件的访问权限位(后面描述)

O_EXCL:若同时指定了O_CREAT标志,而文件已经存在,则会出错。可用于测试文件是否存在open函数返回值int

open(constchar*pathname,int

oflag,…)返回值:整型数据成功时,返回文件描述符出错时,返回-1open函数返回值int

open(constchar*pathname,int

oflag,…)返回值:整型数据成功时,返回文件描述符出错时,返回-1什么是文件描述符?open函数返回值int

open(constchar*pathname,int

oflag,…)返回值:整型数据成功时,返回文件描述符出错时,返回-1什么是文件描述符?已打开文件的索引open函数返回值int

open(constchar*pathname,int

oflag,…)返回值:整型数据成功时,返回文件描述符出错时,返回-1什么是文件描述符?已打开文件的索引通过索引找到已打开文件文件描述符文件描述符的本质是什么?通过文件描述符怎么样能找到需访问的文件?需要了解进程打开文件时,内核创建或涉及到的一系列数据结构进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志............dentryd_inode索引节点号文件各信息inode..............进程打开文件的内核数据结构task_struct.........进程控制块PCB进程打开文件的内核数据结构task_struct.........files.........struct

task_struct{.............

struct

files_struct*files;.............};进程打开文件的内核数据结构task_struct.........files...................files_structfiles_struct该结构体包含了:进程已打开文件表进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]files_struct..............structfile**fd;进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfile..............文件对象:代表一个已打开的文件进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志..............文件偏移量各种文件标志文件相关目录项struct

dentry*f_dentry;进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志............dentry..............进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志............dentryd_inode..............struct

inode*d_inode;进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志............dentryd_inode索引节点号文件各信息inode..............索引节点文件系统索引节点的信息,存储在磁盘上当需要时,调入内存,填写VFS的索引节点(即inode结构)每个文件都对应了一个索引节点通过索引节点号,可以唯一的标识文件系统中的指定文件索引节点struct

inode{........................unsignedlongi_no;

umode_t

i_mode;

uid_t

i_uid;

gid_t

i_gid;

off_t

i_size;

time_t

i_atime;

time_t

i_mtime;};

索引节点struct

inode{........................unsignedlongi_no;

umode_t

i_mode;

uid_t

i_uid;

gid_t

i_gid;

off_t

i_size;

time_t

i_atime;

time_t

i_mtime;};

索引节点号索引节点struct

inode{........................unsignedlongi_no;

umode_t

i_mode;

uid_t

i_uid;

gid_t

i_gid;

off_t

i_size;

time_t

i_atime;

time_t

i_mtime;};

文件类型访问权限索引节点struct

inode{........................unsignedlongi_no;

umode_t

i_mode;

uid_t

i_uid;

gid_t

i_gid;

off_t

i_size;

time_t

i_atime;

time_t

i_mtime;};

文件拥有者ID索引节点struct

inode{........................unsignedlongi_no;

umode_t

i_mode;

uid_t

i_uid;

gid_t

i_gid;

off_t

i_size;

time_t

i_atime;

time_t

i_mtime;};

文件拥有者所在组ID索引节点struct

inode{........................unsignedlongi_no;

umode_t

i_mode;

uid_t

i_uid;

gid_t

i_gid;

off_t

i_size;

time_t

i_atime;

time_t

i_mtime;};

文件大小索引节点struct

inode{........................unsignedlongi_no;

umode_t

i_mode;

uid_t

i_uid;

gid_t

i_gid;

off_t

i_size;

time_t

i_atime;

time_t

i_mtime;};

文件最后访问时间索引节点struct

inode{........................unsignedlongi_no;

umode_t

i_mode;

uid_t

i_uid;

gid_t

i_gid;

off_t

i_size;

time_t

i_atime;

time_t

i_mtime;};

文件最后修改时间进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志............dentryd_inode索引节点号文件各信息inode文件描述符task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志............dentryd_inode索引节点号文件各信息inodeopen函数返回的文件描述符已打开文件表的索引文件描述符文件描述符是已打开文件的索引,通过该值可以在fd_array表中检索相应的文件对象文件描述符是一个非负的整数文件描述符0、1、2分别对应于标准输入、标准输出、标准出错,在进程创建时,已经打开。Open函数(续)Open函数在内核完成的工作:39Namei40程序演示

open函数出错处理(2.1)errno.h头文件中,定义了errno:当API调用出错时,errno说明出错的具体原因可简单地将errno理解成整型数据出错信息转换成可读字符串#include<string.h>

char*strerror(int

errno);程序演示

open函数出错处理以前的定义:extern

int

errno;多线程环境:

externint*__errno_location();

#defineerrno

(*__errno_location())perror函数perror函数根据当前的errno,输出一条出错信息函数原型#include<stdio.h>voidperror(constchar*msg);该函数输出:msg指向的字符串:errno对应的出错信息43文件操作基本顺序打开 open创建

creat定位

lseek读 read写 write关闭 closecreat

函数用于创建一个新文件函数原型

int

creat(constchar*pathname,mode_tmode)参数pathname:要创建的文件名(包括路径信息)mode:同open的第三个参数,讨论文件的访问权限位时分析返回值成功返回只写打开的文件描述符出错返回-1creat函数creat函数的功能可以用open函数实现

open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);为什么需要指定O_TRUNC标志当文件存在时,调用creat函数,会将文件的大小变为0(程序演示2.2)creat函数creat函数缺点:它以只写方式打开所创建的文件。若要创建一个临时文件,并先写该文件,然后又读该文件,则必须先调用creat,close,然后再open。简便方法:

open(pathname,O_RDWR|O_CREAT|O_TRUNC,mode);文件操作基本顺序打开 open创建

creat定位

lseek读 read写 write关闭 closelseek函数lseek函数用于修改当前文件偏移量当前文件偏移量的作用规定了从文件什么地方开始进行读、写操作通常,读、写操作结束时,会使文件偏移量增加读写的字节数当打开一个文件时,除非指定了O_APPEND标志,否则偏移量被设置为0lseek函数函数原型:off_t

lseek(int

filedes,off_toffset,intwhence)参数第一个参数filedes:open/creat函数返回的文件描述符第二个参数offset:相对偏移量:需结合whence才能计算出真正的偏移量类型off_t:通常情况下是32位数据类型lseek函数参数第三个参数Whence:该参数取值是三个常量之一SEEK_SET:当前文件偏移量为:

距文件开始处的offset个字节SEEK_CUR:当前文件偏移量为:

当前文件偏移量+offset(可正可负)SEEK_END:当前文件偏移量为:

当前文件长度+offset(可正可负)lseek函数返回值:若成功,返回新的文件偏移量若出错,返回-1获得当前的偏移量off_t

CurrentPosition;CurrentPosition=lseek(fd,0,SEEK_CUR);lseek操作并不引起任何I/O操作,只是修改内核中的记录进程打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志............dentryd_inode索引节点号文件各信息inode空洞文件使用lseek修改文件偏移量后,当前文件偏移量有可能大于文件的长度在这种情况下,对该文件的下一次写操作,将加长该文件这样文件中形成了一个空洞。对空洞区域进行读,均返回00100150200lseek(fd,50,SEEK_END)write(fd,buf,50)文件长度是多少?200?150?空洞文件演示程序(2.3)#od

file.hole文件操作基本顺序打开 open创建

creat定位

lseek读 read写 write关闭 closeread函数用于从文件中读出数据函数原型

ssize_t

read(int

fd,void*buff,

size_t

nbytes)参数第一个参数fd:文件描述符第二个参数buff:指向缓冲区,用于存放从文件读出的数据第三个参数nbytes:unsigned

int;需要从文件中读出的字节数缓冲区的大小>=nbytesread函数返回值返回值类型:ssize_t,即int出错:返回-1成功:返回从文件中实际读到的字节数当读到文件结尾时,则返回0read函数很多情况下,read实际读出的字节数都小于要求读出的字节数读普通文件,在读到要求的字节数之前,就到达了文件尾端当从终端设备读时,通常一次最多读一行当从网络读时,网络中的缓冲机构可能造成read函数返回值小于所要求读出的字节数某些面向记录的设备,如磁带,一次最多返回一个记录........................Read算法60文件操作基本顺序打开 open创建

creat定位

lseek读 read写 write关闭 closewrite函数用于向文件里面,写入数据函数原型ssize_t

write(int

fd,constvoid*buff,

size_t

nbytes);参数第一个参数fd:文件描述符第二个参数buff:指向缓冲区,存放了需要写入文件的数据第三个参数nbytes:需要写入文件的字节数write函数返回值返回值类型:ssize_t,即int出错:返回-1成功:返回实际写入文件的字节数write出错的原因磁盘满没有访问权限超过了给定进程的文件长度限制.....................write函数当从文件中间某处写入数据时,是插入操作?覆盖操作?还是不能写?(程序演示2.4)当以O_APPEND选项打开一个文件时,能否使用lseek指定文件偏移量?指定之后,从文件什么地方开始进行写?读操作又是如何?(程序演示2.5)文件操作基本顺序打开 open创建

creat定位

lseek读 read写 write关闭 closeclose函数用于关闭一个已打开的文件函数原型int

close(int

filedes)返回值成功返回0出错返回-1参数filedes:文件描述符close函数当clsoe函数关闭文件时,会释放进程加在该文件上的所有记录锁内核会对进程打开文件表、文件对象、索引节点表项等结构进行修改,释放相关的资源当进程退出时,会关闭当前所有已打开的文件描述符文件操作基本顺序打开 open创建

creat定位

lseek读 read写 write关闭 close文件I/O文件的基本操作(打开、定位、读写、关闭)I/O效率文件共享其他重要I/O函数I/O效率程序3-3#defineBUFFSIZE4096intmain(){

intn;charbuf[BUFFSIZE];

while((n=read(STDIN_FILENO,buf,BUFFSIZE))>0)

if(write(STDOUT_FILENO,buf,n)!=n)

err_sys(“writeerror”);return0;}从标准输入读数据然后写至标准输出对标准输入和标准输出进行了重定向:$./test<file1>/dev/null从文件file1读数据然后写至设备/dev/null程序中,影响效率的关键:BUFFSIZE的取值I/O效率BUFFSIZE的取值系统CPU时间I/O效率原因Linux文件系统采用了某种预读技术当检测到正在进行顺序读取时,系统就试图读入比应用程序所要求的更多数据并假设应用程序很快就会读这些数据当BUFFSIZE增加到一定程度后,预读就停止了文件I/O文件的基本操作(打开、定位、读写、关闭)I/O效率文件共享其他重要I/O函数打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志............dentryd_inode索引节点号文件各信息inode打开文件的内核数据结构task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志索引节点号文件各信息inode文件共享进程之间的文件共享进程内的文件共享两个独立进程各自打开同一个文件task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志索引节点号文件各信息inodetask_struct.........files.......................files_structfd[0]fd[1]................fd[4]...........files_structfilef_posf_dentry文件标志进程A进程B两个独立进程各自打开同一个文件每个进程都有自己的当前文件偏移量在完成每个write后,当前文件偏移量即增加所写的字节数如果用O_APPEND标志打开了一个文件,则该标志存储在file结构体中。每次执行写操作时,当前偏移量首先被设置为文件长度不同进程共享文件对象task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志索引节点号文件各信息inodetask_struct.........files.......................files_structfd[0]fd[1]................fd[4]files_struct进程A进程B进程A进程B共享了文件偏移量存在竞争进程内共享文件task_struct.........files.......................files_structfd[0]fd[1]fd[2]fd[3]...........files_structfilef_posf_dentry文件标志索引节点号文件各信息inode造成的原因,通常是调用了dup或dup2函数dup函数用于复制一个已经存在的文件描述符函数原型int

dup(int

filedes);返回值成功返回新的文件描述符出错返回-1参数filedes:文件描述符dup函数的作用task_struct.........files.......................files_structfd[0]fd[1]fd[2].........................files_structfilef_posf_dentry文件标志索引节点号文件各信息inode调用dup函数之前int

fd=dup(1);fd[3]当前未占用文件描述符中的最小值dup函数的作用task_struct.........files.......................files_structfd[0]fd[1]fd[2].........................files_structfilef_posf_dentry文件标志索引节点号文件各信息inodefd[3]使新老文件描述符,都指向同一个文件对象dup2函数用于复制一个已经存在的文件描述符函数原型intdup2(intfiledes,intfiledes2);dup和dup2的区别dup返回的新文件描述符一定是当前可用描述符中的最小值dup2则将文件描述符复制到指定位置,即将filedes复制到filedes2如果filedes2已经打开,dup2则先将其关闭;若filedes2等于filedes,则直接返回filedes,而不关闭dup与dup2的区别假设进程已打开文件描述符0、1、2调用dup2(1,6),dup2返回值是多少?然后再调用dup(6),dup返回值是多少?程序演示验证(2.6)dup函数的作用task_struct.........files.......................files_structfd[0]fd[1]fd[2].........................files_structfilef_posf_dentry文件标志索引节点号文件各信息inode...............fd[6]dup函数的作用task_struct.........files.......................files_structfd[0]fd[1]fd[2].........................files_structfilef_posf_dentry文件标志索引节点号文件各信息inodefd[3]..............fd[6]文件I/O文件的基本操作(打开、定位、读写、关闭)I/O效率文件共享其他重要I/O函数其他重要的I/O函数sync、fsync、fdatasync函数fcntl函数ioctl函数sync/fsync/fdatasync函数通常Linux实现在内核中设有缓冲区高速缓存或页面高速缓存大多数的磁盘I/O都通过缓冲区进行当将数据写入文件时,内核通常先将数据复制到某一个缓冲区中如果该缓冲区满或者内核需要重用该缓冲区,则将该缓冲排入到输出队列等到其达到队首时,才进行实际的磁盘读写操作延迟写sync/fsync/fdatasync函数磁盘文件系统高速缓存应用程序用户模式内核模式sync/fsync/fdatasync函数延迟写优点减少了磁盘读写次数延迟写缺点降低了文件内容的更新速度当系统发生故障,高速缓冲区中的内容可能丢失解决办法对缓冲区进行清理,希望将数据写入到磁盘sync、fsync、fdatasync起到了刷缓存的作用sync函数sync原型:voidsync();将所有修改过的缓冲区排入写队列,然后就返回并不等待实际的写磁盘操作结束sync函数针对的是所有修改过的缓冲区,并不仅仅针对某个被修改过的文件通常称为update的系统守护进程会周期性地调用sync函数,即保证定期冲洗内核缓冲区fsync函数函数原型:

int

fsync(int

filedes);参数与返回值:filedes:文件描述符返回值:成功返回0,出错返回-1fsync函数只对文件描述符filedes指定的单一文件起作用并且等待写磁盘操作结束后才返回fdatasync函数函数原型

int

fdatasync(int

filedes);参数与返回值filedes:文件描述符返回值:成功返回0,出错返回-1fdatasync和fsync类似,但它只影响文件的数据部分;而fync不仅影响文件的数据,还同步更新文件的属性。对比syncfsyncfdatasync是否等待写否是是是否更新数据否是是是否更新属性否是否其他重要的I/O函数sync、fsync、fdatasync函数fcntl函数ioctl函数fcntl函数用于改变已经打开文件的性质函数原型int

fcntl(int

filedes,int

cmd,.../*int

arg*/);返回值成功时,返回值依赖于第二个参数cmd出错时,返回-1参数第一个参数filedes:已打开文件的文件描述符fcntl函数第二个参数cmd的五种取值方式:复制一个现存的描述符(cmd=F_DUPFD)获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)获得/设置文件状态标志(cmd=F_GETFL或F_SETFL)获得/设置异步I/O信号接收进程(cmd=F_GETOWN或F_SETOWN)获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW)cmd五种取值方式F_DUPFD复制文件描述符filedes,与dup(2)类似fcntl返回新文件描述符新描述符是尚未打开的各描述符中,大于或等于第三个参数值中,各值的最小值例子:假设文件描述符0、1、2被占用,

fcntl(1,F_DUPFD,5)返回什么???

fcntl(2,F_DUPFD,1)返回什么???与dup、dup2的异同fcntl函数与dup、dup2函数均用于复制文件描述符,即使不同的文件描述符指向同一个文件对象dup(filedes)等价于

fcntl(filedes,F_DUPFD,0);dup2(filedes,filedes2)不完全等价于close(filedes2);

fcntl(filedes,F_DUPFD,filedes2);与dup、dup2的异同fcntl与dup2不完全等价dup2是一个原子操作,而close与fcntl则包括两个函数调用。在close和fcntl之间可能被信号打断dup2与fcntl之间有某些不同的errnocmd五种取值方式F_DUPFDF_GETFD将文件描述符filedes对应的标志,作为返回值返回。当前只定义了一个文件描述符标志FD_CLOEXECF_SETFD设置文件描述符filedes对应的标志。新标志按照第三个参数设置。cmd五种取值方式F_GETFLfcntl函数返回文件描述符filedes对应的文件状态标志文件状态标志包括:O_RDONLYO_WRONLYO_RDWRO_APPENDO_NONBLOCK 非阻塞方式O_SYNC 等待写方式O_ASYNC 异步方式(仅4.3+BSD)cmd五种取值方式F_SETFL将fcntl函数的第三个参数,设置为文件状态标志可以更改的标志包括:O_APPEND、O_NONBLOCK、O_SYNC、O_ASYNCF_GETOWN获取当前接收SIGIO和SIGURG信号的进程ID或进程组IDcmd五种取值方式F_SETOWN设置接收SIGIO和SIGURG信号的进程ID或进程组ID第三个参数arg:arg>0时,表示一个进程IDarg<0时,其绝对值表示一个进程组IDfcntl函数--实例1(2.7)实例1:获取文件状态标志代码演示

int

fd=open(.......);

int

val=fcntl(fd,F_GETFL);

int

accmode=val&O_ACCMODE;O_ACCMODE=30......0011O_RDONLY=0O_WRONLY=1O_RDWR=2对应的是最低的两位bit取val最低的两位即获取了文件打开模式fcntl函数--实例1对于非打开模式标志:

if(val&O_APPEND){//文件状态标志中包括O_APPEND}O_APPEND=1024第11个bit为1,其余为0.即第11位对应了O_APPEND标志取val第11位查看是否为1fcntl函数--实例2实例2:添加或删除某个文件状态标志添加或删除某个文件描述符标志或文件状态标志时,先将现有标志值存放在某个变量中,再对该变量进行修改,最后将该变量设置为新的标志。不能只是执行F_SETFD或F_SETFL命令,这样会关闭以前设置的标志位。fcntl函数--实例2代码:voidset_fl(int

fd,intflags){

int

val;if((val=fcntl(fd,F_GETFL,0))<0)

err_sys("fcntlF_GETFLerror");

val |= flags;if(fcntl(fd,F_SETFL,val)<0)

err_sys("fcntlF_SETFLerror");}若清除某标志:val&=~flags;其他重要的I/O函数sync、fsync、fdatasync函数fcntl函数ioctl函数ioctl函数I/O操作的杂物箱其实现的功能往往和具体的设备有关系设备可以自定义自己的ioctl命令操作系统提供了通用的ioctl命令ioctl类似于windows的DeviceIoControl函数第三章文件I/O小节文件的基本操作(打开、定位、读写、关闭)I/O效率文件共享其他重要I/O函数第二讲

文件的操作文件I/O(第三章)文件和目录(第四章)文件和目录ext2文件系统在磁盘的组织stat、fstat、lstat函数文件的基本性质修改文件属性的函数硬链接与符号链接目录操作文件和目录ext2文件系统在磁盘的组织stat、fstat、lstat函数文件的基本性质修改文件属性的函数硬链接与符号链接目录操作ext2文件系统在磁盘上的组织ext2文件系统是Linux土生土长的文件系统ext2是ext(ExtendedFileSystem)的完善,因此,ext2为TheSecondExtendedFileSystemext2文件系统加上日志支持,即ext3ext2和ext3在磁盘上的布局大致相同,只是ext3多出了一个特殊的inode,用于记录文件系统日志磁盘布局假设ext2文件系统所占的分区磁盘布局分区被划分成一个个的块block,每个块均有编号

同一个文件系统中,block的大小都是相同的

不同的文件系统,block的大小可以不同典型的block大小为1k或者4k块1.........块m-1块m..........块p块0磁盘布局分区被划分成一个个的块block块1.........块m-1块m..........块p块0块组0块组1块组2..........块组n-1块组n

若干块聚集在一起,形成一个块组

分区被划分成若干个块组

每个块组所包括的块个数相同磁盘布局分区被划分成一个个的块block块1.........块m-1块m..........块p块0块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块

每个块组都包含有一个相同的超级块

超级块重复的主要目的:灾难恢复

超级块用于存放文件系统的基本信息磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块s_magic:ext2文件系统标识0xef53

s_log_block_size:可由它得出块大小

块组包括的块个数、包括的索引节点个数,总的块个数磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块

bg_block_bitmap:指向块位图

bg_inode_bitmap:指向索引节点位图

bg_inode_table:指向索引节点表磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块当某个bit为1,表示该bit对应的数据块被占用

当某个bit为0,表示该bit对应的数据块未被占用磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块当某个bit为1,表示该bit对应的索引节点被占用

当某个bit为0,表示该bit对应的索引节点未被占用磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块

索引节点表由若干个索引节点组成

一个索引节点对应了一个文件(目录也是一种文件)每个索引节点都有一个编号,这个编号是全局的,从1开始计数索引节点包含的信息structext3_inode{__u16i_mode; //Filemode__u16i_uid; //Low16bitsofOwnerUid

__u32i_size; //文件大小__u32i_atime; //Accesstime__u32i_ctime; //Creationtime__u32i_mtime; //Modificationtime__u16i_gid; //Low16bitsofGroupId__u16i_links_count;

//Linkscount__u32i_flags; //Fileflags__u32i_block[EXT3_N_BLOCKS];

//一组block指针,

//存储了文件的内容................................................};目录目录也是一种文件通过其索引节点中的i_block字段,可以找到存放目录文件内容的数据块目录的内容具有固定的格式目录文件按照固定的格式记录了目录包含了哪些文件目录项目录中每个文件,都对应了一个目录项若干个目录项构成了目录文件的内容structext3_dir_entry_2{__u32inode;/*Inode

号数*/__u8file_type;charname[EXT3_NAME_LEN];//Filename..........................};问题如何在ext2文件系统中找到一个文件?假设查找文件/root/test假设/root的索引节点号已知,为1400磁盘布局超级块组描述符块位图索引节点位图索引节点表数据块s_magic:ext2文件系统标识0xef53

s_log_block_size:可由它得出块大小

块组包括的块个数、块组包括的索引节点个数,总的块个数s_inodes_per_group1400-13001399商4,余199磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块

bg_block_bitmap:指向块位图

bg_inode_bitmap:指向索引节点位图

bg_inode_table:指向索引节点表磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块.........索引节点1300..........索引节点1400..........磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块.........索引节点1300..........索引节点1400..........块指针..........磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块.........索引节点1300..........索引节点1400..........块指针...................数据块..........数据块..........磁盘布局块组0块组1块组2..........块组n-1块组n超级块组描述符块位图索引节点位图索引节点表数据块.........索引节点1300..........索引节点1400..........块指针...................数据块..........数据块..........索引节点号2300文件名test....................文件和目录ext2文件系统在磁盘的组织stat、fstat、lstat函数文件的基本性质修改文件属性的函数硬链接与符号链接目录操作stat函数用于获取有关文件的信息结构函数原型

int

stat(constchar*restrictpathname,

structstat*restrict

buf);restrict关键字restrict关键字C99标准引入的只能用于限定指针表明指针是访问一个数据对象的唯一且初始的方式restrict关键字intar[10];int*restrictrestar=(int*)malloc(10*sizeof(int));int*par=ar;for(intn=0;n<10;n++){

par[n]+=5;

restar[n]+=5;

ar[n]*=2;

par[n]+=3;

restar[n]+=3;}对于malloc分配的这段内存只能通过restar访问int*pnew=restar;restrict关键字intar[10];int*restrictrestar=(int*)malloc(10*sizeof(int));int*par=ar;for(intn=0;n<10;n++){

par[n]+=5;

restar[n]+=5;

ar[n]*=2;

par[n]+=3;

restar[n]+=3;}对于malloc分配的这段内存只能通过restar访问int*pnew=restar;restrict关键字intar[10];int*restrictrestar=(int*)malloc(10*sizeof(int));int*par=ar;for(intn=0;n<10;n++){

par[n]+=5;

restar[n]+=5;

ar[n]*=2;

par[n]+=3;

restar[n]+=3;}对restar的操作进行优化,restar[n]+=8无法对par的操作优化par[n]+=8什么是编译单元?stat函数用于获取有关文件的信息结构函数原型int

stat(constchar*restrictpathname,

structstat*restrict

buf);参数与返回值第一个参数pathname:文件名,需要获取该文件的信息第二个参数buf:stat函数将pathname对应的文件信息,填入buf指向的stat结构中返回值:0成功;-1出错stat结构体structstat{.......................................................

ino_t

st_ino; /*inodenumber*/

mode_t

st_mode;/*filetype&mode*/

nlink_t

st_nlink; /*numberofhardlinks*/

uid_t

st_uid; /*userIDofowner*/

gid_t

st_gid; /*groupIDofowner*/

off_t

st_size; /*totalsize,inbytes*/unsignedlong st_blksize; /*blocksize*/unsignedlong st_blocks; /*numberofblocksallocated

time_t

st_atime; /*timeoflastaccess*/

time_t

st_mtime;/*timeoflastmodification*/

time_t

st_ctime; /*timeofinodelastchange};fstat、lstat函数用于获取有关文件的信息结构函数原型

int

stat(constchar*restrictpathname,

structstat*restrictbuf);

int

fstat(int

filedes,structstat*buf);

int

lstat(constchar*restrictpathname,

structstat*restrictbuf);lstat返回符号链接本身的信息stat返回符号链接所引用的文件信息fstat、lstat函数用于获取有关文件的信息结构函数原型

int

stat(constchar*restrictpathname,

structstat*restrictbuf);

int

fstat(int

filedes,structstat*buf);

int

lstat(constchar*restrictpathname,

structstat*restrictbuf);Stat通过文件名返回文件的信息fstat通过文件描述符程序演示演示stat的使用(2.8)文件和目录ext2文件系统在磁盘的组织stat、fstat、lstat函数文件的基本性质修改文件属性的函数硬链接与符号链接目录操作文件的基本性质文件类型用户ID和组ID文件访问权限新文件和目录的所有权文件时间文件的基本性质文件类型用户ID和组ID文件访问权限新文件和目录的所有权文件时间文件类型UNIX或Linux系统中的常见文件类型有:普通文件

目录文件

字符特殊文件

提供对设备不带缓冲的访问块特殊文件

提供对设备带缓冲的访问FIFO文件 用于进程间的通信,命名管道

套接口文件

用于网络通信符号链接

使文件指向另一个文件152stat结构体structstat{.......................................................

ino_t

st_ino; /*inodenumber*/

mode_t

st_mode;/*filetype&mode*/

nlink_t

st_nlink; /*numberofhardlinks*/

uid_t

st_uid; /*userIDofowner*/

gid_t

st_gid; /*groupIDofowner*/

off_t

st_size; /*totalsize,inbytes*/unsignedlong st_blksize; /*blocksize*/unsignedlong st_blocks; /*numberofblocksallocated

time_t

st_atime; /*timeoflastaccess*/

time_t

st_mtime;/*timeoflastmodification*/

time_t

st_ctime; /*timeofinodelastchange};包含了文件类型信息文件类型的判定使用如下的宏,判断文件类型普通文件 S_ISREG()目录文件 S_ISDIR()字符特殊文件 S_ISCHR()块特殊文件 S_ISBLK()FIFO文件 S_ISFIFO()套接口文件 S_ISSOCK()符号连接 S_ISLINK()154文件类型示例代码:

structstatbuf;lstat(filename,&buf);

if(S_ISDIR(buf.st_mode))

cout<<“directory”<<endl;注意,此处必须用lstat获取文件信息,而不用stat,为什么?155程序演示文件类型的判定(2.9)156文件的基本性质文件类型用户ID和组ID文件访问权限新文件和目录的所有权文件时间用户ID和组ID第一种ID:Linux是一个多用户的操作系统。每个用户都有一个ID,用以唯一标识该用户。这个ID,被称为UID。每个用户都属于某一个组,组也有一个ID。这个ID,被称为组ID,GID。第二种ID:文件所有者相关文件所有者ID:拥有某文件的用户的ID文件所有者组ID:拥有某文件的用户所属组的IDstat结构体structstat{.......................................................

ino_t

st_ino; /*inodenumber*/

mode_t

st_mode;/*filetype&mode*/

nlink_t

st_nlink; /*numberofhardlinks*/

uid_t

st_uid; /*userIDofowner*/

gid_t

st_gid; /*groupIDofowner*/

off_t

st_size; /*totalsize,inbytes*/unsignedlong st_blksize; /*blocksize*/unsignedlong st_blocks; /*numberofblocksallocated

time_t

st_atime; /*timeoflastaccess*/

time_t

st_mtime;/*timeoflastmodification*/

time_t

st_ctime; /*timeofinodelastchange};用户ID和组ID第三种ID:实际用户ID和实际组ID进程的实际用户ID:运行该进程的用户的ID进程的实际组ID:运行该进程的用户所属的组ID第四种ID:有效用户ID和有效组ID进程的有效用户ID:用于文件访问权限的检查进程的有效组ID:程序演示(2.10)大多数情况下有效用户/组ID=实际用户/组ID用户ID和组ID设置用户ID位和设置组ID位在可执行文件的权限标记中,有一个“设置用户ID位”若该位被设置,表示:执行该文件时,进程的有效用户ID变为文件的所有者对于设置组ID位类似通过命令行设置用户ID位(2.11)chmod

u+sfilename

chmod

g+sfilenamechmod

u-sfilename

chmod

g-sfilename用户ID和组ID第五种ID:保存的设置用户ID保存的设置组ID上述两者在执行一个程序时包含了有效用户ID和有效组ID的副本文件的基本性质文件类型用户ID和组ID文件访问权限新文件和目录的所有权文件时间文件访问权限什么是文件访问权限?为什么要有访问权限?每一个文件都有访问权限位,可将其分成三类文件访问权限针对文件所有者针对与文件所有者同组的用户针对非同组的用户指定所有者是否可读指定组用户是否可读指定其他用户是否可读指定所有者是否可写指定组用户是否可写指定其他用户是否可写指定所有者是否可执行指定组用户是否可执行指定其他用户是否可执行stat结构体structstat{.......................................................

ino_t

st_ino; /*inodenumber*/

mode_t

st_mode;/*filetype&mode*/

nlink_t

st_nlink; /*numberofhardlinks*/

uid_t

st_uid; /*userIDofowner*/

gid_t

st_gid; /*groupIDofowner*/

off_t

st_size; /*totalsize,inbytes*/unsignedlong st_blksize; /*blocksize*/unsignedlong st_blocks; /*numberofblocksallocated

time_t

st_atime; /*timeoflastaccess*/

time_t

st_mtime;/*timeoflastmodification*/

time_t

st_ctime; /*timeofinodelastchange};包含了文件访问权限位st_mode字段76543210111098st_mode的低11bitst_mode字段76543210111098st_mode的低11bit针对文件所有者的访问权限st_mode字段76543210111098st_mode的低11bit指示文件所有者是否可执行指示文件所有者是否可写指示文件所有者是否可读st_mode字段76543210111098st_mode的低11bit针对与文件所有者同组的用户的访问权限st_mode字段76543210111098st_mode的低11bit指示组用户是否可执行指示组用户是否可写指示组用户是否可读st_mode字段76543210111098st_mode的低11bit针对其他用户的访问权限st_mode字段76543210111098st_mode的低11bit指示其他用户是否可执行指示其他用户是否可写指示其他用户是否可读st_mode字段76543210111098st_mode的低11bit9个文件访问权限位判定文件访问权限的屏蔽字(2.13)st_mode屏蔽意义S_IRUSR用户-读S_IWUSR用户-写S_IXUSR用户-执行S_IRGRP组-读S_IWGRP组-写S_IXGRP组-执行S_IROTH其他-读S_IROTH其他-写S_IWOTH其他-执行if(buf.st_mode&S_IRUSR){用户可读}open的第三个参数creat的第二个参数st_mode字段76543210111098st_mode的低11bit9个文件访问权限位设置用户ID设置组ID粘住位文件存取许可权(续)当打开一个任意类型的文件时,对该文件路径名中包含的每

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论