【linux编程实践教程(Bruce Molay)】第四章 文件系统:编写pwd

一 磁盘基础知识(非常通俗易懂)

磁盘基本知识(磁头,磁道)

  1. 扇区: 硬盘的最小读写单元
  2. 磁盘块/簇: 是操作系统针对硬盘读写的最小单元
  3. page: 是内存与操作系统之间操作的最小单元。
  4. 不同长度的磁道,扇区容量与个数是否相同?(磁道由外向内编号,最外圈是0磁道)
  5. 如果有一块空硬盘,写入一个文件,是不是先写满同一个磁道的所有扇区,然后再换一个磁道写入
    --------是的,而且写入的方式是从外到内,先写满最外的磁道,接着再写里面的磁道
    为什么硬盘用久了读写速度会变慢?因为外面的磁道使用完了,开始用里面的磁道,越是里面的磁道读写速度越慢,同样的时间,读写头在外面磁道可以扫过10个扇区的面积,读写10个扇区的数据,但在里面的磁道只能扫过1个扇区的面积,读写1个扇区的数据,所以这时可以做磁盘整理或者格式化,这会使外面的磁道得到使用

二 文件系统的内部结构

0-术语概念

  1. 入口:目录中的列表的每一行就是一个入口(引用,硬链接)
  2. 符号链接(symlink):符号链接是通过文件名引用文件,而不是i-节点号

1-文件系统理解

磁盘分为最小单位扇区—>若干扇区又组成一个磁盘块—>磁盘块的序列又划分为三大部分:

  1. 超级块:文件系统的第一个磁盘块(什么是文件系统?文件系统的分类有哪些?)
  2. i-节点表:存放文件的属性信息(通常由系统调用stat得到),一个文件由一个i-结点唯一标识,一个i结点中有个数据块列表在这里插入图片描述该数据块列表存储了数据块(都在数据区中)的位置序号(该文件的内容就存储在这些数据块中)
  3. 数据区:存放文件中的内容数据—>存放在若干磁盘块中(可以不连续)

2-目录是一种特殊文件

形象化理解:目录中存储着一个列表,列表的每一行代表着该目录下的一个文件或者目录,每一行有两个数据(一个是i-结点号,一个是文件名)在这里插入图片描述

3-大文件的存储

  1. 一个 i-节点的数据块列表的长度是有限的
  2. 需要间接块,二级间接块,三级间接块
    例:一个文件,它的i-节点的数据块列表长度为10,现在已经占据了7个位置。为防止表空间不够用,就在数据区开辟一个数据块,作为一个新数据块列表来存储数据块的位置序号,在i结点的数据块列表中,存放该新数据块的位置序号,此时该数据块被称为间接块。
  3. 间接块满时,在i结点中中存放二级间接块的的位置序号,二级间接块中存放(第2,3,4…块)间接块的位置序号。
  4. 二级间接块满时,开辟三级间接块,依次类推
  5. 最多只有三级间接块,再满了…买新硬盘吧

三 编写pwd命令

  1. stdout与stderr
    * stdout与stderr都是把内容打印到终端界面
    * stdout(标准输出),输出方式是行缓冲。输出的字符会先存放在缓冲区,等按下回车键时才进行实际的I/O操作。
    * stderr(标准错误),是不带缓冲的,这使得出错信息可以直接尽快地显示出来。
    * 因此,通常来说,输出到stderr的内容会比stdout更快打印出来(除非遇到换行符’\n’)
  2. 编写思路
    1. 首先得到当前目录的inode
    2. 然后系统调用chdir("…")回到上级目录,在上级目录中根据inode找到本级目录的名字,存储下来。递归函数完成后,打印输出。
    3. 继续得到当前目录的inode,并回到上级目录
    4. 显然的递归思路方法—重要的一点便是路径的打印:先递归,递归到底后就倒着打印文件名,进行输出,便解决了字符串的连接问题,直接输出路径
      代码如下:
#include<dirent.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
char buffer[256];

int printPath(ino_t);
void ino_to_name(ino_t,char*);
ino_t get_inode(char*);

int main(){
    printPath(get_inode("."));
    printf("\n");
    return 0;
}
int printPath(ino_t inode){
    ino_t pre_inode=get_inode("..");

    if(pre_inode!=inode){
    char name[255];
    memset(name,0,sizeof(name));
     chdir("..");
    ino_to_name(inode,name); 
    printPath(get_inode("."));
    printf("%s/",name);
    return 1;
    }
    return 0;
}
void ino_to_name(ino_t inode,char*buf){
    DIR* dir;
    dir=opendir(".");
    struct dirent *tmp=(struct dirent*)malloc(sizeof(struct dirent));
    if(dir==NULL){
        perror("目录打开失败");
        return;
    }
    memset(buf,0,sizeof(buf));
    while(  (  tmp=readdir(dir)  )  !=  NULL){
        if(tmp->d_ino==inode){
            strcpy(buf,tmp->d_name);
            closedir(dir);
            return;
        }
    }
}
ino_t get_inode(char*filename){
    char buf[256];
    struct stat tmp;
    if(stat(filename,&tmp)){
        perror("无法获取文件信息");
        return -1;
    }
    return tmp.st_ino;
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值