代码示例支持
平台: Mac OS
Python: 2.7.10
代码示例:
- wx: 菜单 - Python踩坑指南代码示例
- github 见code_demo

1.1 案例

这期案例讲的是Unix-Like系统中, 常听到的一句话: 目录也是个文件 或者 everything is a file.

刚接触 Linux 文件系统的同学有时候听到这个很懵, 目录怎么是个文件呢?目录不应该是内部包含文件的载体么?

1.2 分析

分析主要从2个方面展开:

  • ls 实际是使用大量文件系统标准接口实现的结果, 是处理过后的用户程序
  • 从文件系统的组织结构来看穿数据存储和读写方式

如果大家已习惯了 Linux 系统中 ls 命令 (有时候由于alias 存在, 实际是ls --color), 容易产生一种错觉:文件夹和文件这不是天然的被区分为不同的类别了吗?

  • 比如蓝色的文件夹?
  • 黑色的文件?`

实际不是这样子的, ls mkdir touch 一类的文件系统操作命令其实是通过调用文件系统接口实现的用户态程序, 你自己利用python也可以实现一个一摸一样的.

我们来看一些使用 python 访问文件系统的简单例子:

from __future__ import print_function
import os # 简单文件写
with open('./test', 'w+') as fhandle:
fhandle.write('test\n') # 创建文件夹 dirname = os.path.abspath('./test_dir')
if not os.path.exists(dirname):
os.makedirs(dirname) for ind in range(0, 10):
with open('{0}/test_file_{1}'.format(dirname, ind), 'w+') as fhandle:
fhandle.write('1')
dname = '{0}/test_dir_{1}'.format(dirname, ind)
if not os.path.exists(dname):
os.mkdir(dname) # 读文件夹
for obj in os.listdir(dirname):
objpath = os.path.join(dirname, obj)
if os.path.isfile(objpath):
print('{0} is a file'.format(objpath))
elif os.path.isdir(objpath):
print('{0} is a dir'.format(objpath))

因此, 大家理解 ls 类耳熟能详的 Linux 命令是经过代码实现的用户程序, 如果你想且有时间完成可以实现一个 python 版 的ls


更进一步的说, 对文件或者文件夹的操作本质上是用户层的代码实现调用了系统相关的接口. 这代表着文件夹和文件对系统来讲, 就是数据组织上的不同 (数据结构的不同). 那数据或者文件数目是怎么进行组织的?

想了解这个问题就要先了解 Linux 系统上的文件存储层次, 以在 Linux 上挂载的文件系统进程读写为例:

  • 最上层, 用户的程序进程 Process, 通过调用类似open write close 等通用系统函数读写所在挂载目录的文件

  • 中间 Kernel VFS (Virtual Filesystem, 虚拟文件系统)

    • 市面上主流的文件系统并不少, 为了让上层应用不关心如何读写这些内部实现各异的文件系统, Kernel 实现了虚拟文件系统
    • 虚拟文件系统包含一系列的标准;
      • 为了方便理解, 可以简化理解为提供了一系列读写接口标准
      • 上层用户应用使用下层的文件系统不需要关心你是哪个文件系统, 我只要挂载好你到我的系统就能使用标准接口读写
  • 底层, Kernel 内核, 各个设备厂家不同的VFS实现嵌入 kernel 中以支持具体的读写等操作

  • 物理介质层 (块设备等), 真正的硬件设备层

而我们要聚焦到 VFS 这层来看, 因为它:

  1. 屏蔽下层不同设备厂商数据存储实现
  2. 抽象并统一了数据存储接口

只要明白了它如何组织文件/文件夹, 基本上就明白了人们常说 everything is a file 的意思.

具体到数据结构上, 要看虚拟文件系统上规定了针对文件系统的4类数据结构:

  • superblock

    • 用来存储挂载的文件系统的元信息 (比如inode 数目等)
    • 简化理解起来就像是文件系统的索引系统, superblock 决定了如下几个数据结构的分布
  • inode, 用来存储具体数据的单元 (包括人们通常理解的 file 实体和文件夹)
  • dentry, directory entry, 用来描述文件夹信息
  • file obj, 进程打开文件描述

对VFS来讲, 无论是存储了具体字节数据的文件, 还是文件夹, 本质都是个 inode 作元信息描述的逻辑结构.

无非文件夹不包括具体数据信息描述, 但包含一些指针 (指向该文件夹包含的一系列数据文件或者子文件夹). 相反, 一个指向数据的 inode 不包含子目录或文件们.

1.3 扩展

基本了解了文件系统的组织方式后, 留几个问题大家给大家做扩展思考?

  1. 通常我们说一个文件系统满盘了, 可能扩展哪几种满盘?
  2. 我只创建文件夹但不创建文件, 文件系统会满盘么?
  3. 文件系统有时候出现错乱, 需要进行 fs check, 这个时候可能是什么坏掉了?

1.4 技术关键字

关键字

  1. Linux Kernel
  2. VFS
  3. Inode / Dentry / Superblock

一些可以参考的资料

下期预告

文件系统篇 Umask 到底影响了谁


  • 水平有限, 有问题欢迎指正.
  • Life is short. We use Python

Python 踩坑之旅文件系统篇其一文件夹也是个文件的更多相关文章

  1. Python 踩坑之旅进程篇其三pgid是个什么鬼 (子进程\子孙进程无法kill 退出的解法)

    目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4.1 技术关键字 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 Github: https: ...

  2. [代码修订版] Python 踩坑之旅 [进程篇其四] 踩透 uid euid suid gid egid sgid的坑坑洼洼

    目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 公 ...

  3. Python 踩坑之旅进程篇其四一次性踩透 uid euid suid gid egid sgid的坑坑洼洼

    目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 菜 ...

  4. [代码修订版] Python 踩坑之旅进程篇其五打不开的文件

    目录 1.1 踩坑案例 1.2 填坑和分析 1.2.1 从程序优化入手 1.2.2 从资源软硬限入手 1.4.1 技术关键字 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: ...

  5. Python踩坑之旅其一杀不死的Shell子进程

    目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 坑后扩展 1.4.1 扩展知识 1.4.1 技术关键字 1.5 填坑总结 1.1 踩坑案例 踩坑的程序是个常驻的Agent类管理进程 ...

  6. Python踩坑之旅其二裸用os.system的原罪

    目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4.1 技术关键字 1.5 填坑总结 2. 前坑回顾 2.1 Linux中, 子进程拷贝父进程哪些信息 2.2 Agent常驻进程选择& ...

  7. 美团热修复Robust的踩坑之旅-使用篇

    最近需要在项目中使用热修复框架,在这里以美团的Robust为主写一篇文章总结一下学习的过程. 一直认为要学习一个框架的原理,首先需要让他跑起来,从效果反推回去,这样更容易理解. 一.美团Robust的 ...

  8. vue+ vue-router + webpack 踩坑之旅

    说是踩坑之旅 其实是最近在思考一些问题 然后想实现方案的时候,就慢慢的查到这些方案   老司机可以忽略下面的内容了 1)起因  考虑到数据分离的问题  因为server是express搭的   自然少 ...

  9. 微信小程序之mpvue+iview踩坑之旅

    因为之前参照微信的原生的文档写过一些小程序的demo,写的过程比较繁琐,后来出了美团的mpvue,可以直接使用vue开发,其他的不作对比,这篇文章记录一下踩坑之旅. 参照mpvue http://mp ...

随机推荐

  1. idea快速生成实体类

    1.打开idea的视图,选择Database 2.选择对应的数据库[这里是mysql为例] 3.输入自己对应的内容,输入完成可点击Test Connection进行测试,成功SUCCESS 4.点击确 ...

  2. 2018年蓝桥杯b组国赛真题

    1.标题:换零钞x星球的钞票的面额只有:100元,5元,2元,1元,共4种.小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱.小明有点强迫症,他坚持要求200元换出 ...

  3. 原来update还可以这么用,一切都是这么神奇。

    update sys_user_info a left join union_menber_info b on a.user_cardno = b.member_cardno set a.user_s ...

  4. HMM学习

    参看博客: 1.https://www.cnblogs.com/skyme/p/4651331.html 2.https://blog.csdn.net/continueoo/article/deta ...

  5. Mysql如何添加外键,如何实现连表查询

    创建表student和表score,表student设置主键,表score设置表student中属性相同的为外键: 创建student表 create table student ( id int p ...

  6. 百度地图api之----根据用户ip定位城市

    LocalCity 这个类是利用用户IP地址去百度数据库里查询得到IP所在的城市,用法如下: var objCity = new BMap.LocalCity(); objCity.get(funct ...

  7. 前端利器躬行记(3)——webpack基础

    webpack是一个静态模块打包器,此处的模块可以是任意文件,包括Sass.TypeScript.模板和图像等.webpack可根据输入文件的依赖关系,打包输出浏览器可识别的JavaScript.CS ...

  8. CodeForces 474F Ant colony ST+二分

    Ant colony 题解: 因为一个数是合法数,那么询问区间内的其他数都要是这个数的倍数,也就是这个区间内的gcd刚好是这个数. 对于这个区间的gcd来说,不能通过前后缀来算. 所以通过ST表来询问 ...

  9. hdu 3038 How Many Answers Are Wrong(并查集的思想利用)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038 题意:就是给出n个数和依次m个问题,每个问题都是一个区间的和,然后问你这些问题中有几个有问题,有 ...

  10. CSU 1804: 有向无环图 拓扑排序 图论

    1804: 有向无环图 Submit Page   Summary   Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 716    ...