首页 > 系统相关 >《Unix/Linux系统编程》第七、八章学习笔记

《Unix/Linux系统编程》第七、八章学习笔记

时间:2022-09-25 20:49:03浏览次数:44  
标签:count 文件 八章 int char Unix u32 Linux 链接

第七章 文件操作

7.1 文件操作级别

文件操作分为五个级别,按照从高到低的顺序排列如下:
(1)硬件级别

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

(2)操作系统内核中的文件系统函数
(3)系统调用
(4)I/O库函数
(5)用户命令
(6)sh脚本


7.2 文件I/O操作

用户模式下的程序执行操作

FILE *fp = fopen("file", "r");

FILE *fp = fopen("file", "w");

可以打开一个读/写文件流。


7.3 低级别文件操作

7.3.1 分区

一个块存储设备,如硬盘、U盘、SD卡等,可以分为几个逻辑单元,称为分区。各分区均可以格式化为特定的文件系统,也可以安装在不同的操作系统上。大多数引导程序,如GRUB、LILO等,都可以配置为从不同的分区引导不同的操作系统。分区表位于第一个扇区的字节偏移446(0x1BE)处,该扇区称为设备的主引导记录(MBR)。表有4个条目,每个条目由一个16字节的分区结构体定义,即:

struct 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),那么它可以划分为更多分区。

7.3.2 格式化分区

fdisk只将一个存储设备划分为多个分区。每个分区都有特定的文件系统类型,但是分区还不能使用。为了存储文件,必须先为特定的文件系统准备好分区。该操作习惯上称为格式化磁盘或磁盘分区。在Linux中,它被称为mkfs,表示Make文件系统。Linux支持多种不同类型的文件系统。每个文件系统都期望存储设备上有特定的格式。在Linux中,命令
mkfs -t TYPE [-b bsize] device nblocks
在一个nblocks设备上创建一个TYPE文件系统,每个块都是bsize字节。如果bsize未指定,则默认块大小为1KB。具体来说,假设是EXT2/3文件系统,它是Linux的默认文件系统。因此,
mkfs -t ext2 vdisk 1440

mke2fs vdisk 1440
使用1440(1KB)个块将vdisk格式化为EXT2文件系统。格式化后的磁盘应是只包含根目录的空文件系统。但是,Linux的mkfs始终会在根目录下创建一个默认的lost+found目录。
/mnt目录通常用于挂载其他文件系统。


7.4 EXT2文件系统简介

7.4.2 超级块

Block#1:超级块(在硬盘分区中字节偏移量为1024)B1是超级块,用于容纳关于整个文件系统的信息。下文说明了超级块结构中的一些重要字段。

struct ext2_super_block {
    u32 s_inodes_count;         // Inodes count
    u32 s_blocks_count;         // Blocks count
    u32 s_r_blocks_count;       // Reserved blocks count
    u32 s_free_blocks_count;    // Free blocks count
    u32 s_free_inodes_count;    // Free inodes count
    u32 s_first_data_block;     // First Data Block
    u32 s_log_block_size;       // Block size
    u32 s_log_cluster_size;     // Allocation cluster size
    u32 s_blocks_per_group;     // # Blocks per group
    u32 s_clusters_per_group;   // # Fragments per group
    u32 s_inodes_per_group;     // # Inodes per group
    u32 s_mtime;                // Mount time
    u32 s_wtime;                // Write time
    u32 s_mnt_count;            // Mount count
    u16 s_max_mnt_count;        // Maximal mount count
    u16 s_magic;                // Magic signature
    // more non-essential fields
    u16 s_inode_size;           // size of inode structure
};
7.4.3 块组描述符

Block#2:块组描述符块(硬盘上的s_first_data_blocks-1)EXT2将磁盘块分成几个组。每个组有8192个块(硬盘上的大小为32K)。每组用一个块组描述符结构体描述。

7.4.4 位图

Block#8:块位图(Bmap)(bg_block_bitmap)位图用来表示某种项的位序列,例如,磁盘块或索引节点。位图用于分配和回收项。
在位图中,0位表示对应项处于FREE状态,1位表示对应项处于IN_USE状态。一个软盘有1440块。
Block#9:索引节点位图(Imap)(bg_inode_bitmap)一个索引节点就是用来代表一个文件的数据结构。EXT2文件系统是使用有限数量的索引节点创建的。各索引节点的状态用B9中Imap中的一个位表示。在EXT2 FS中,前10个索引节点是预留的。

7.4.5 索引节点

Block#10:索引(开始)节点块(bg_inode_table)每个文件都用一个128字节(EXT4中的是256字节)的独特索引节点结构体表示。

7.4.6 目录条目

EXT2目录条目:目录包含dir_entry_2结构,即:

struct ext2_dir_entry_2 {
    u32 inode;
    u16 rec_len;
    u8 name_len;
    u8 file_type;
    char name[EXT2_NAME_LEN];
};

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

8.1 系统调用

在操作系统中,进程以两种不同的模式运行,即内核模式和用户模式,简称Kmode和Umode。在Umode中,进程的权限非常有限。它不能执行任何需要特殊权限的操作。特殊权限的操作必须在Kmode下执行。系统调用(简称syscall)是一种允许进程进入Kmode以执行Umode不允许操作的机制。复刻子进程、修改执行映像,甚至是终止等操作都必须在内核中执行。


8.2 系统调用手册页

在Unix以及大多版本的Linux中,在线手册页保存在/usr/man/目录中(Goldt等1995;Kerrisk 2010,2017)。而在Ubuntu Linux中,则保存在/usr/share/man目录中。man2子目录中列出了所有系统调用手册页。sh命令man 2 NAME显示了系统调用名称的手册页。
例如:

man 2 stat:display man pages of stat(),fstat() and lstat() syscalls
man 2 open:display man pages of open() syscall
man 2 read:display man pages of read() syscall,etc.

许多系统调用需要特别包含头文件,手册页的SYNOPSIS(概要)部分列出来这些文件。如果没有合适的头文件,会有警告。


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

系统调用必须由程序发出。它们的用法就像普通函数调用一样。每个系统调用都是一个库函数,它汇集系统调用参数,并最终向操作系统内核发出一个系统调用。


8.4 常规的系统调用

本节讨论一些最常见的文件操作的系统调用。
stat:获取文件状态信息

int stat(char *filename, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(char *filename, struct stat *buf);

open:打开一个文件进行读、写、追加

int open(char *file, int flags, int mode);

close:关闭打开的文件描述符

int close(int fd);

read:读取打开的文件描述符

int read(int fd, char buf[], int count);

write:写入打开的文件描述符

int write(int fd, char buf[], int count);

lseek:重新定位文件描述符的读/写偏移量

int lseek(int fd, int offset, int whence);

dup:将文件描述符复制到可用的最小描述符编号中

int dup(int oldfd);

dup2:将oldfd复制到newfd中,如果文件链接数为0,则删除文件

int dup2(int oldfd, int newfd);

link:将新文件硬链接到旧文件

int link(char *oldPath, char *newPath);

unlink:取消某个文件的链接;如果文件链接数为0,则删除文件

int unlink(char *pathname);

symlink:创建一个符号链接

int symlink(char *target, char *newpath);

readlink:读取符号链接文件的内容

int readlink(char *path, char *buf, int bufsize);

umask:设置文件创建掩码;文件权限为(mask & ~umask)

int umask(int umask);

8.5 链接文件

在Unix/Linux中,每个文件都有一个路径名。但是,Unix/Linux允许使用不同的路径名来表示用一个文件。这些文件叫作LINK(链接)文件。有两种类型的链接,即硬链接和软链接或符号链接。

8.5.1 硬链接文件

硬链接:命令

ln oldpath newpath

创建从newpath到oldpath的硬链接。对应的系统调用为:

link(char *oldpath, char *newpath)

硬链接文件会共享文件系统中相同的文件表示数据结构(索引节点)。文件链接数会记录链接到同一索引节点的硬链接数量。硬链接仅适用于非目录文件。否则,它可能会在文件系统名称空间中创建循环,这是不允许的。相反,系统调用:

unlink(char *pathname)

会减少文件的链接数。如果链接数变为0,文件会被完全删除。这就是rm(file)命令的作用。如果某个文件包含非常重要的信息,就最好创建多个链接到文件的硬链接,以防被意外删除。

8.5.2 符号链接文件

软链接:命令

ln -s oldpath newpath   # ln command with the -s flag

创建从newpath到oldpath的软链接或符号链接。对应的系统调用是:

symlink(char *oldpath, char *newpath)

newpath是LNK类型的普通文件,包含oldpath字符串。它可作为一个绕行标志,使访问指向链接好的目标文件。与硬链接不同,软链接适用于任何文件,包括目录。软链接在以下情况下非常有用。
(1)通过一个较短的名称来访问一个经常使用的较长的路径名称,例如:

x -> aVeryLongPathnameFile

(2)将标准动态库名称链接到实际版本的动态库,例如:

libc.so.6 -> libc.2.7.so

当将实际动态库更改为不同版本时,库安装程序只需更改(软)链接以指向新安装的库。
软链接的一个缺点是目标文件可能不复存在了。如果是这样,绕行标志可能引导可怜的司机摔下悬崖。在Linux中,会通过ls命令以适当的深色RED显示此类危险,提醒用户链接已断开。此外,如果foo -> /a/b/c是软链接,open("foo", 0)系统调用将打开被链接的文件/a/b/c,而不是链接文件自身。所以open()/read()系统调用不能读取软链接文件,反而必须要用readlink系统调用来读取软链接文件的内容。

标签:count,文件,八章,int,char,Unix,u32,Linux,链接
From: https://www.cnblogs.com/qwer6653/p/16728773.html

相关文章

  • 第七八章
    一、学习笔记二、遇到问题Eachdirectoryinthepathnameprecedingthedirectorytobeopened使用cat命令,由于缺少可执行(x)权限,该目录下的文件不可读三、解决......
  • Linux pssh安装与使用
    Linuxpssh安装与使用说明:我这是没有在密钥认证的情况下操作1、安装pssh[root@libinansible]#yuminstall-ypssh[root@libinansible]#rpm-qlpssh/usr/bin/pnuk......
  • 弃用 Windows,政府机构 5000 万台电脑将替换为国产 Linux!
    来源:https://www.linuxmi.com/50-million-pc-linux.html开源社区的一大胜利!继德国之后,中国现在想在5000万台PC上抛弃Windows并运行Linux!如果您一直密切关注Lin......
  • Linux错题集1
    错题1在Linux系统中,小王希望将他执行ls命令的输出结果保存在当前目录下的文件output.ls中,以供日后进行分析和使用,但要求不覆盖原文件的内容,他应该使用的命令是A.ls>outpu......
  • 第七八章学习笔记
    7.1文件操作级别文件操作分为五个级别:(1)硬件级别:·fdisk:将硬件、U盘或SDC盘分区。·mkfs:格式化磁盘分区,为系统做好准备。·fsck:检查和维修系统。·碎片整理:压缩文件系......
  • 20201302姬正坤第七八章学习笔记
    Linux系统编程第七、八章学习笔记——文件操作&使用系统调用进行文件操作一、文件操作类别1、硬件类别disk:将硬盘、U盘或SDC盘分区。mkfs:格式化磁盘分区,为系统做好准......
  • 在Linux下的文件IO的使用(一)
    系统调用系统调用:操作系统提供给用户程序调用的一组“特殊”接口,用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务为什么用户程序不能直接访问系......
  • 20201318李兴昕第七、八章学习笔记
    第七章:文件操作知识点总结:本章讨论了多种文件系统;解释了操作系统中的各种操作级别,包括为文件存储准备存储设备、内核中的文件系统支持函数、系统调用、文件流上的I/O库函......
  • UnixBench的简单测试与验证
    UnixBench的简单测试与验证目标飞腾2000+(物理机和虚拟机)IntelGolden6170物理机IntelGolden5218虚拟机[email protected]至强十年前的CPUE5-262......
  • 第七/八章读书笔记
    第七章文件操作一、文件操作级别(五个阶别,5/6一个级别,由低到高)一、硬件级别文件操作大部分创建和维护系统必不可少的工具如fdisk二、操作系统内核的文件系统......