学习笔记4(第七、八章)

一、知识点归纳

(一)第七章

7.1 文件操作

文件操作可以分为以下五个级别,它们从低到高的顺序排列如下:

1. 硬件级别

硬件级别的文件操作包括以下几种:

  • fdisk:将硬盘、U盘或SDC盘分区。
  • mkfs:格式化磁盘分区,为系统做好准备。
  • fsck:检查和维修系统。
  • 碎片整理;压缩文件系统中的文件。

注意:其中大多数是针对系统的实用程序。普通用户可能永远都不需要它们,但是它们是创建和维护系统不可缺少的工具。

2. 操作系统内核中的文件系统函数

每个操作系统内核都可以为基本文件操作提供支持。以下是类Unix系统内核中的一些函数,其中前缀k表示内核函数。

 kmount () . kumount ( )			(mount/umount file systems)
 kmkdir(), krmdir()				    (make/ remove directory)
 kchdir(), kgetcwd ()				(change directory, get CWD pathname)
 klink(),kunlink()				    (hard link/unlink files)
 kchmod(), kchown(),kutime()		(change r|w|x permissions, owner,time)
 kcreat (), kopen()					(create/open file for R,W,RW,APPEND)
 kread(),kwrite()					(read/write opened files)
 klseek(): kclose()					(lseak/close file descriptors)
 ksymlink(), kreadlink ()			(create/read symbolic link files)
 kstat(), kfstat(),klstat()			(get file status/information)
 kopendir(), kreaddiz()				(open/read airectories)

3. 系统调用

用户模式程序使用系统调用来访问内核函数。例如open(), read(), lseek()close()都是C语言库函数。每个库函数都会发出一个系统调用,使进程进入内核模式来执行相应的内核函数。

4. I/O库函数

系统调用可以让用户读/写多个数据块,这些数据块只是一系列字节。由于用户并不关心这些数据的意义,因此,C语言提供了一套标准的I/O函数,同时也提高了运行效率。

这些函数主要包括:

  • FILE mode I/O: fopen(), fread(), fwrite(), fseek(), fclose(), fflush()
  • char mode I/O: getc(), getchar(), ugetc(), putc(), putchar()
  • line mode I/O: gets(), fgets(), puts(), fputs()
  • formatted I/O: scanf(), fscanf(), sscanf(), printf(), fprintf(), sprintf()

5. 用户命令

用户可以使用Unix/Linux命令来执行文件操作,而不是编写程序。例如:mkdirrmdircdpwdlslinkunlinkrmcatcpmvchmod,等等。

注意:每个用户命令实际上是一个可执行程序,通常为库I/O函数。其顺序如下:
Command => Library I/O function => System call => Kernel Function

7.2文件I/O操作

文件I/O操作
文件I/O操作

7.3低级别文件操作

(1)分区

一个块存储设备可以分为几个逻辑单元称为分区。各分区均可格式化为特定的文件系统,也可以安装在不同的操作系统上。分区表位于第一个扇区的字节偏移446(ox1BE)处,该扇区称为设备的主引导记录。表有4个条目,每个条目由一个16字节的分区结构体定义,即:

stuct partition {

u8 drive;			// 0x80 - active

u8 head;			// starting head

u8 sector;			// starting sector

u8 cylinder;		// starting cylinder

u8 sys_type;		// partition type 

u8 end_head;		// end head

u8 end_sector;		// end sector

u8 end_cylinder;	// end cylinder

u32 start_sector;	// starting sector counting from 0 

u32 nr_sectors;		// number of sectors in partition )

如果某分区是扩展类型(类型编号=5),那么它可以划分为更多分区。假设分区P4是扩展类型,它被划分为扩展分区P5、P6、P7。扩展分区在扩展分区区域内形成一个链表。

每个扩展分区的第一个扇区是一个本地MBR。每个本地MBR在字节偏移量0xIBE处也有一个分区表,只包含两个条目。第一个条目定义了扩展分区的起始扇区和大小。第二个条目指向下一个本地MBR。所有本地MBR的扇区编号都与P4的起始扇区有关。照例,链表以最后一个本地MBR中的0结尾。在分区表中,CHS值仅对小于8GB的磁盘有效。对大于8GB但小于4G扇区的磁盘,只有最后两个条目start _sector 和nr sector有意义。

(2)格式化分区

fdisk只是将一个存储设备划分为多个分区。每个分区都有特定的文件系统类型,但是分区还不能使用。为了存储文件,必须先为特定的文件系统准备好分区。该操作习惯上称为格式化磁盘或磁盘分区。在Linux中,命令

mkfs -t TYPE [-b bsize] device nblocks

在一个nblocks设备上创建一个TYPE文件系统,每个块都是bsize字节。如果bsize未指定,则默认大小为1KB。例如假设是EXT2/3文件系统,它作为Linux的默认文化系统,因此,

mkfs -t ext2 vdisk 1440

使用1440个块将vdisk格式化为EXT2文件系统。

在Linux中,还不能访问新的文件系统。它必须挂在到跟文件系统中的现有目录。由于细腻文件系统不是真正的设备i,他们必须作为循环设备挂载,如:

sudo mount -o loop vdisk /mnt

将 vdisk挂载到/mnt 目录中。不带任何参数的 mount命令会显示Linux系统的所有挂载设备。挂载完成后,挂载点/mnt 改变,与挂载设备的根目录相同。用户可以将目录(cd)更改为/mnt,像往常一样对设备进行平铺操作。挂载后的设备使用完成后,将cd从/mnt中取出,然后输入

sudo umount /mnt 

以卸载设备,将其与根文件系统分离。设备上保存的文件应保留在该设备中。

(3)挂载分区

man 8 losetup:显示用于系统管理的losetup 实用工具命令(实践截图)

7.4 EXT2文件系统简介

(二)第八章 使用系统调用进行文件操作

本章主要介绍如何使用系统调用进行文件操作,探讨了系统调用的作用,并列举了常用的系统调用。此外,还具体介绍了stat系统调用等内容。

8.1 系统调用及Linux在线手册

  • 进程的运行模式

    • 操作系统中的进程在两种模式下运行:内核模式(Kmode)和用户模式(Umode)。
    • 在Umode中,进程权限有限,不能执行特权操作。这些操作必须在Kmode下执行。
    • 系统调用(syscall)允许进程从Umode切换到Kmode以执行特权操作。
  • 在线手册的位置

    • Unix和大部分Linux版本:/usr/man/
    • Ubuntu Linux:/usr/share/man
    • 查看系统调用名称的手册页:man 2 NAME

8.2 使用系统调用进行文件操作

int syscall(int a, int b, int c, int d);

其中:

a:系统调用编号
b, c, d:对应内核函数的参数

8.3 链接文件

硬链接:

命令:ln oldpath newpath
系统调用:link(char *oldpath, char *newpath)

软链接(符号链接):

命令:ln -s oldpath newpath
系统调用:link(char *oldpath, char *newpath)

8.4 stat系统调用

stat系统调用

(三)苏格拉底挑战

问题一
问题一
问题二
问题二

二、问题与解决思路

(一) 文件描述符与打开文件之间的关系

Linux系统中采用一个理念:一切皆文件。这包括普通文件、目录文件、链接文件和设备文件。为了理解文件描述符和打开文件之间的关系,我们需要深入研究以下几个方面:

1. 文件描述符

文件描述符(file descriptor)是Linux系统用于引用已经打开的文件的索引。它是一个非负整数,并通常是一个较小的数。例如,标准输入、标准输出和标准错误对应的文件描述符分别是0、1和2。当您打开一个新的文件时,它的文件描述符通常会是3(假设您没有关闭前面的描述符)。

2. 进程与文件的关系

  • 同一文件可以被多次打开,无论是在同一个进程还是不同的进程。
  • 每个进程有其独立的文件描述符表。
  • 尽管在不同的进程中,文件描述符的数值可能相同(如3),但它们可以引用不同的文件。

3. 关键数据结构

为了理解文件描述符与打开文件之间的关系,我们需要深入了解Linux内核维护的以下三个数据结构:

  1. 进程级的文件描述符表

    • 它为每个进程维护一个独立的文件描述符表。
  2. 系统级的打开文件描述符表

    • 它为每个打开的文件都有一个条目。
    • 这意味着,如果同一文件被多次打开(即使是由同一进程),在此表中都会有多个条目。
  3. 文件系统的i-node表

    • 每个文件在磁盘上都有一个与之对应的i-node,其中存储了文件的元数据,例如权限、大小和时间戳。
    • 当文件被打开时,其i-node被加载到内存中。

通过这三个数据结构的互动,Linux系统能够高效地跟踪每个进程中打开的文件,并确保文件的并发访问不会导致数据冲突或不一致。
文件问题1
文件问题2
文件问题3

三、实践过程

(一)挂载分区


posted @ 2023-09-30 18:31  6666666mjz  阅读(54)  评论(0)    收藏  举报