系統知識坑窪之旅文件系統篇其一文件夾也是個文件?

代碼示例支持
平臺: Mac OS
Python: 2.7.10
代碼示例:
- wx: 菜單 - Python踩坑指南代碼示例
- github 見code_demo

1.1 案例

這期案例講的是Unix-Like系統中, 常聽到的一句話: 目錄也是個文件 或者 everything is a file.
剛接觸 Linux 文件系統的同窗有時候聽到這個很懵, 目錄怎麼是個文件呢?目錄不該該是內部包含文件的載體麼?node

1.2 分析

分析主要從2個方面展開:python

  • ls 實際是使用大量文件系統標準接口實現的結果, 是處理事後的用戶程序
  • 從文件系統的組織結構來看穿數據存儲和讀寫方式

若是你們已習慣了 Linux 系統中 ls 命令 (有時候因爲alias 存在, 實際是ls --color), 容易產生一種錯覺:文件夾和文件這不是自然的被區分爲不一樣的類別了嗎?git

  • 好比藍色的文件夾?
  • 黑色的文件?`

實際不是這樣子的, ls mkdir touch 一類的文件系統操做命令實際上是經過調用文件系統接口實現的用戶態程序, 你本身利用python也能夠實現一個一摸同樣的.github

咱們來看一些使用 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函數


更進一步的說, 對文件或者文件夾的操做本質上是用戶層的代碼實現調用了系統相關的接口. 這表明着文件夾和文件對系統來說, 就是數據組織上的不一樣 (數據結構的不一樣). 那數據或者文件數目是怎麼進行組織的?spa

想了解這個問題就要先了解 Linux 系統上的文件存儲層次, 以在 Linux 上掛載的文件系統進程讀寫爲例:unix

  • 最上層, 用戶的程序進程 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
相關文章
相關標籤/搜索