学习笔记4(必做)20191216赵子瑜
第七八章 文件操作和使用系统调用进行文件操作
本章介绍各种文件系统。多种操作的操作系统级别,如文件存储,文件系统功能,系统调用和用户命令的存储设备准备。和各种SH脚本操作。全身解释的各种操作,包括在主要空间的读/写文件的流量。截至驱动程序级别的I / O的结束
讲述的低级别的文件操作,例如磁盘分区,分区表程序实例中,文件的文件格式的分区,和磁盘分区坐骑。介绍了Linux系统,它包含的数据系统结构的ext2文件系统。文件系统EXT2显示用于超级块,组描述符,索引块,节点的节点,并且内容目录的示例程序。
编程项目转换ext2文件/ 3文件系统,并计划在本章中所描述的技术,转换名路径索引节点,并打印信息。
一:文件操作级别:
Linux提供目录和文件级别的权限管理。每个文件和目录都有一个owner(所有者)和一个group(用户组)。一个文件或目录可以对owner、所属group中的用户和其他所有用户开放不同的权限。
对于一个文件,“r”代表读权限,“w”代表写权限。
对于一个目录,“r”代表查看目录下内容的权限,“w”代表在目录中创建或删除新的文件或目录的权限,“x”代表访问该目录的子目录的权限。
和权限有关的是“drwxr-xr-x”、“root”和“root”这三个字段。其中:
第一个字段“drwxr-xr-x”包含了下面信息:
第一个字符显示该行末尾的路径是文件还是目录:
如果第一个字符是“d”代表该路径对应一个目录;
如果第一个字符是“-”则代表该路径对应一个文件。
后九个字符可分为三组三个的字符:
第一组的三个字符代表该路径的owner的权限;
第二组的三个字符代表该路径所属的group的权限;
第三组的三个字符代表所有其他用户对该路径拥有的权限。
每组三个字符中的第一个对应“r”,第二个对应“w”,第三个对应“x”,如果对应的位置显示是字
母,则代表对应用户有字母所代表的权限,如果是“-”则代表没有权限。
操作系统下文件系统的“rwx”权限可以用数字表示——比如“rwxrwxrwx” =777,“rwxr-xr-x” = 755等等。rwxrwxrwx表示的二进制为:111 111 111=7 7 7,表示owner的权限为rwx,group的权限为rwx,其他用户的权限为rwx。
第二个字段“root”对应着该行末尾路径的owner。
第三个四段“root”对应该行末尾路径所属的group。
二:低级别文件操作(此处结合实践内容)
1 打开文件
f=open(r'D:\脱产5期内容\day09\a.txt',mode='rt',encoding='utf-8')
print(f)
2 读/写文件
data=f.read()/write()
3 关闭文件
f.close() # 向操作系统发送指令,让操作系统关闭打开的文件,回收操作系统资源
print(f)
f.read()
控制文件读写操作的模式
r(默认):只读模式,以该模式打开文件,当文件不存在时则报错,当文件存在时文件指针在文件开头
with open('a.txt',mode='rt',encoding='utf-8') as f:
read()
f.readable()是否可读?
f.writable() 是否可写?
f.readline()一次读取一行
for line in f:
print(line) 可以使用for循环打印文件内容
readlines()将文件所有内容读入一个列表中,且每一行为一个元素,包括换行符\n
w: 只写模式,以该模式打开文件,当文件不存在时创建一个空文档,当文件存在时清空文件内容,文件指针在文件开头
writable()是否可写
在打开了文件不关闭的情况下,连续的写入,新写的内容总是跟在老内容之后
三.EXT2文件系统
D-Recovery For Linux是在windows平台下安装使用,对EXT2/EXT3/EXT4文件系统的分区进行读取并进行数据恢复,具备如下功能:1、 扫描并恢复丢失的EXT2/EXT3/EXT4文件系统分区,也就是分区表恢复。2、 EXT2/EXT3/EXT4超级块损坏,可以通过扫描找出超级块备份。若超级块备份全部损坏,可以虚构超级块相关信息虚拟出分区信息。 3、 能自动识别采用LVM管理方式的硬盘分区。LVM管理是LINUX下常用的磁盘分区管理方式,通过对LVM结构的解析,在软件中模拟LINUX下LVM管理分区方式读取分区信息。4、 LINUX下大于2TB的分区通常采用GPT分区管理方式进行分区,D-Recovery For Linux能识别GPT分区,并能导出数据。5、 对于EXT3/EXT4文件系统下的删除恢复,通过分析journal日志文件,提取被删除的文件信息。6、 手工构建inode信息,导出相应文件。7、 磁盘镜像功能(可以把磁盘镜像到新的磁盘,也可以把磁盘镜像成一个文件)。
int unlink(const char *pathname); 删除pathname
目录下的文件其实就是该目录下有指针指向了文件在磁盘中的位置,删除文件就是讲指向该文件的链表结点删除。
2.读取目录:
①.打开目录:DIR* opendir(const char* name);
返回值是一个指向dir结构体的指针,用于读取目录数据。失败返回NULL
②.读取目录下的文件:struct dirent* readdir(DIR* dirp)
返回一个目录项的信息,包括文件的inode节点号和文件名,目录指针指向下一个目录项;
③:关闭目录:int close(DIR* dirp);
疑问:
当时疑惑如何获取当前文件的文件名、行号等信息
发现编译器有几个内置的宏可以比较方便的得到当前的文件信息;
比较重要的就是文件名:__FILE__;
行号:__LINE__;
既然C标准库和系统调用都能够操作文件,那么应该选择哪种操作呢?考虑的因素如下:
-
使用系统调用会影响系统的性能。执行系统调用时,Linux需要从用 户态切换至内核态,执行完毕再返回用户代码,所以减少系统调用能减 少这方面的开销。如库函数写入数据的文件操作fwrite最后也是执行了write系统 调用,如果是写少量数据的话,直接执行write可能会更高效,但如果是频繁的写入操作,由于f write的缓冲区可以减少调用write的次数,这种情况下使用fwrite能更节省时间。
-
硬件本身会限制系统调用本身每次读写数据块的大小。如针对某种存 储设备的write函数每次可能必须写4kB的数据,那么当要写入的实际数据小于4kB时,write也只能 按4kB写入,浪费了部分空间,而带缓冲区的fwrite函数面对这种情况,会尽量在满足数据长度要求时才执行系统调用,减少空间开销。
-
也正是由于库函数带缓冲区,使得我们无法清楚地知道它何时才会真正地把内容写入到硬件上,所以在需 要对硬件进行确定的控制时,我们更倾向于执行系统调用。