Python 踩坑之旅文件系统篇其一文件夹也是 File Object

2019-09-23 10:26:09 +08:00
 mythmgn

1.1 案例

这期案例讲的是 Unix-Like 系统中, 常听到的一句话: 目录也是个文件 或者 everything is a file. 和 Python 踩坑联系不紧密, 目标是方便大家理解 文件夹以及文件 在 类 Unix 系统上的读写方式.

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

1.2 分析

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


如果大家已习惯了 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 上挂载的文件系统进程读写为例:

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

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

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

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

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

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

1.3 扩展

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

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

1.4 技术关键字

关键字

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

一些可以参考的资料

下期预告

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


一些可以长期关注地方:

2744 次点击
所在节点    Python
7 条回复
ps1aniuge
2019-09-23 12:38:40 +08:00
powershell (.net )没这问题。文件夹,文件,是不同对象。
Nitroethane
2019-09-23 12:52:00 +08:00
“只要明白了它如何组织文件 /文件夹, 基本上就明白了人们常说 everything is a file 的意思”
你怕是还不明白 everything is a file 的意思,每个打开的 socket 是一个 file,每个设备是一个 file,每个 pipe 也是 file,然而这些跟“它如何组织文件 /文件夹”没有关系
swulling
2019-09-23 13:13:21 +08:00
这个和 Python 踩坑之旅关系不大吧,最近看了一篇 300 行实现文件系统的,可以看看

https://cloud.tencent.com/developer/article/1497058
mythmgn
2019-09-23 14:25:03 +08:00
@Nitroethane

文件系统中的 directory 是最容易来理解 everything is a file 的示例.

(你说的 socket 也好, pipe 也好, 也都是的.
前几年一直在做分布式文件系统相关项目, 当然理解这些道理. )


但请仔细看下我想表达的目标, 更多的针对 Directory 啊....
mythmgn
2019-09-23 14:25:40 +08:00
@swulling 是的. 关系不大. 我在文里也提到了. 只是顺带写入这个系列了 哈哈 :)
mythmgn
2019-09-23 14:31:57 +08:00
@Nitroethane 像 pipe 可能还要分 named pipe, anonymous pipe. 存储方式在文件系统上还不一样. 但这不是重点, 写这个更多的针对人群是还不明白为啥文件夹也是文件? 这是为什么? :)
no1xsyzy
2019-09-23 15:59:43 +08:00
@ps1aniuge .Net 部分符合 POSIX 规范
FileInfo 和 DirectoryInfo 都是 System.IO.FileSystemInfo

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/603236

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX