11. 文件和目录访问¶
这个模块提供了代表文件系统路径的类,其语义适用于不同的操作系统。
文件类继承图

11.1. pathlib¶
11.1.1. 基本使用¶
# 列出目录下的所有文件
In [1]: from pathlib import Path
In [2]: p=Path(".")
In [3]: [ x for x in p.iterdir() if x.is_dir() ]
Out[3]:
[WindowsPath('.vscode'),
WindowsPath('node_modules'),
WindowsPath('public'),
WindowsPath('scaffolds'),
WindowsPath('source'),
WindowsPath('themes'),
WindowsPath('tmp')]
# 所有特定的文件,glob使用通配功能,递归需要**
In [7]: list(p.glob("**/*.rst"))
Out[7]:
WindowsPath('source/_posts/CA服务器的搭建.rst'),
WindowsPath('source/_posts/mariadb多实例的三种实现.rst'),
# 导航目录
In [14]: p = Path('/etc')
In [15]: p
Out[15]: WindowsPath('/etc')
In [16]: q = p / 'init.d' / 'reboot'
In [17]: q
Out[17]: WindowsPath('/etc/init.d/reboot')
# 基础文件判断
In [20]: q.exists()
Out[20]: False
In [21]: q.is_dir()
Out[21]: False
In [22]: q.is_file()
Out[22]: False
11.1.2. pure路径¶
# 路径整合
In [24]: from pathlib import PurePath
In [25]: PurePath('foo', 'some/path', 'bar')
Out[25]: PureWindowsPath('foo/some/path/bar')
In [26]: str(PurePath('foo', 'some/path', 'bar'))
Out[26]: 'foo\\some\\path\\bar'
In [33]: os.fspath(PurePath('foo', 'some/path', 'bar'))
Out[33]: 'foo\\some\\path\\bar'
# 路径判断,window是不区分大小写的,linux区分大小写(更准确的说应该是文件系统)
In [28]: from pathlib import *
In [29]: PurePosixPath('foo') == PurePosixPath('FOO')
Out[29]: False
In [30]: PureWindowsPath('foo') == PureWindowsPath('FOO')
Out[30]: True
# 文件系统路径
In [32]: import os
In [33]: os.fspath(PurePath('foo', 'some/path', 'bar'))
Out[33]: 'foo\\some\\path\\bar'
# 路径拆分
In [37]: p=PureWindowsPath('c:/Program Files/')
In [38]: p.parts
Out[38]: ('c:\\', 'Program Files')
# 驱动盘
In [39]: p.drive
Out[39]: 'c:'
# 根
In [40]: p.root
Out[40]: '\\'
# 锚定
In [41]: p.anchor
Out[41]: 'c:\\'
#父目录
In [42]: p.parents
Out[42]: <PureWindowsPath.parents>
In [43]: p.parents[0]
Out[43]: PureWindowsPath('c:/')
# 文件名
In [46]: p.name
Out[46]: 'Program Files'
# 没有扩展的名字a.tar 得到a
In [47]: p.stem
Out[47]: 'Program Files'
# url路径
In [49]: p.as_uri()
Out[49]: 'file:///c:/Program%20Files'
11.1.3. Concrete路径¶
在原有PurePath的基础上又提供了对路径对象执行系统调用的方法。
# 当前目录,current workspace directory
In [51]: Path.cwd()
Out[51]: WindowsPath('E:/ZhaojiediProject/github/My_Aliyun_Hexo_Blog/hexo')
# 当前用户的家目录
In [52]: Path.home()
Out[52]: WindowsPath('C:/Users/Administrator')
# 目录是否存在
In [53]: Path(".").exists()
Out[53]: True
# 其他方法
In [57]: Path.
absolute() chmod() expanduser() is_absolute() is_fifo()
anchor cwd() glob() is_block_device() is_file()
as_posix() drive group() is_char_device() is_reserved() >
as_uri() exists() home() is_dir() is_socket()
11.2. os.path¶
这个模块算是用的比较多的,目录判断和文件相关的大部分功能都有。
os.path.abspath(path) 绝对路径
os.path.basename(path) 基名
os.path.commonpath(paths) 公共路径
os.path.commonprefix(list) 公共前缀
os.path.dirname(path) 目录名
os.path.exists(path) 存在判断
os.path.lexists(path) 链接文件存在判断
os.path.expanduser(path) 解析~这里路径
os.path.expandvars(path) 解析变量
os.path.getatime(path) atime
os.path.getmtime(path) mtime
os.path.getctime(path) ctime
os.path.getsize(path) 文件大小
os.path.isabs(path) 判断绝对路径
os.path.isfile(path) 判断是否是文件
os.path.isdir(path) 判断是否是目录
os.path.islink(path) 判断是否是链接文件
os.path.ismount(path) 判断是否是一个挂载点
os.path.join(path, *paths) 合并路径
os.path.normcase(path) 忽略大小写路径
os.path.normpath(path) A//B, A/B/, A/./B and A/foo/../B all become A/B
os.path.realpath(path) 相对路径
os.path.relpath(path, start=os.curdir) 相对路径
os.path.samefile(path1, path2) 相同文件
os.path.sameopenfile(fp1, fp2) 相同文件描述符
os.path.samestat(stat1, stat2) 相同stat信息
os.path.split(path) 路径分割
os.path.splitdrive(path) 分割驱动盘
os.path.splitext(path) 扩展,用于提取不带扩展的文件名字
11.3. fileinput¶
该模块实现了一个辅助类和函数,可以在标准输入或文件列表上快速编写循环。
import fileinput
for line in fileinput.input():
print(line)
11.4. stat¶
stat模块定义用于解释os.stat(),os.fstat()和os.lstat()(如果它们存在)的结果的常量和函数。
stat.S_ISDIR(mode) 是否是一个目录
stat.S_ISCHR(mode) 字符设备
stat.S_ISBLK(mode) 块设备
stat.S_ISREG(mode) 普通文件
stat.S_ISFIFO(mode) 管道文件
stat.S_ISLNK(mode) 连接文件
stat.S_ISSOCK(mode) socket文件
stat.S_ISDOOR(mode) 不清楚这个
stat.S_ISPORT(mode) 时间端口
stat.S_ISWHT(mode) 不清楚
stat.S_IMODE(mode) mode信息,可以后续使用so.chmod
stat.S_IFMT(mode)
stat.filemode(mode) 转化为string格式的-rwxrwxrwx
stat.ST_MODE inode包括mode
stat.ST_INO inode号码
stat.ST_DEV
stat.ST_NLINK inode的连接个数
stat.ST_UID 所有者
stat.ST_GID 所属组
stat.ST_SIZE 大小
stat.ST_ATIME atime
stat.ST_MTIME mtime
stat.ST_CTIME ctime
stat.S_IFSOCK socket
stat.S_IFLNK 符号连接
stat.S_IFREG 普通文件
stat.S_IFBLK 块设备
stat.S_IFDIR 目录
stat.S_IFCHR 字符
stat.S_IFIFO 管道
stat.S_IFDOOR
stat.S_IFPORT
stat.S_IFWHT
stat.S_ISUID uid
stat.S_ISGID gid
stat.S_ISVTX
stat.S_IRWXU 对于所有者的掩码
stat.S_IRUSR 所有者是否有读权限
stat.S_IWUSR 所有者是否有写权限
stat.S_IXUSR 所有者是否有执行权限
stat.S_IRWXG 组的掩码
stat.S_IRGRP 组能读文件
stat.S_IWGRP 组能写文件
stat.S_IXGRP 组能执行文件
stat.S_IRWXO 其他用户的掩码
stat.S_IROTH 其他读
stat.S_IWOTH 其他写
stat.S_IXOTH 其他执行
stat.S_ENFMT
stat.S_IREAD
stat.S_IWRITE
stat.S_IEXEC
stat.UF_NODUMP
stat.UF_IMMUTABLE
stat.UF_APPEND
stat.UF_OPAQUE
stat.UF_NOUNLINK
stat.UF_COMPRESSED
stat.UF_HIDDEN
stat.SF_ARCHIVED
stat.SF_IMMUTABLE
stat.SF_APPEND
stat.SF_NOUNLINK
stat.SF_SNAPSHOT
In [76]: mode =os.stat(".").st_mode
In [77]: stat.S_ISDIR(mode)
Out[77]: True
11.5. filecmp¶
这个目录定义了一些文件和目录比较的功能。
report() 报告比较信息
report_partial_closure() 报告包括自路径
report_full_closure() 公共子目录的比较
left 第一个比较的目录a
right 第二个比较的目录b
left_list 目录a,隐藏文件被忽略
right_list 右侧b,
common 公共的文件和目录
left_only 只在a目录里面存在的文件和目录
right_only 只在b目录里面存在的文件和目录
common_dirs 目录a和目录b公共的目录
common_files 目录a和目录b公共的文件
common_funny
same_files 相同的文件
diff_files 不同的文件
funny_files
subdirs
# 文件比较的
In [1]: import filecmp
In [2]: filecmp.cmp("a.txt","b.txt")
Out[2]: False
下面的代码在linux测试的。
root@centos-7 tmp]# tree
.
├── dir1
│ ├── sub1
│ │ └── a.txt
│ ├── sub2
│ └── sub3
└── dir2
├── sub1
│ └── aa.txt
├── sub2
└── sub4
[root@centos-7 tmp]# bpython
bpython version 0.16 on top of Python 2.7.5 /usr/bin/python
>>> import filecmp
>>> filecmp.dircmp("dir1","dir2")
<filecmp.dircmp instance at 0x1799a28>
>>> info = filecmp.dircmp("dir1","dir2")
>>> info.left
'dir1'
>>> info.right
'dir2'
>>> info.report
<bound method dircmp.report of <filecmp.dircmp instance at 0x1799a70>>
>>> info.report()
diff dir1 dir2
Only in dir1 : ['sub3']
Only in dir2 : ['sub4']
Common subdirectories : ['sub1', 'sub2']
11.6. tempfile¶
从名字上就知道这个是临时文件相关的。
比较简单,直接上个例子吧。
# 使用临时文件
In [1]: import tempfile
In [2]: fp =tempfile.TemporaryFile()
In [3]: fp.write(b'my name is zhaojiedi')
Out[3]: 20
In [4]: fp.seek(0)
Out[4]: 0
In [5]: fp.read()
Out[5]: b'my name is zhaojiedi'
In [6]: fp.close()
# 直接创建一个临时文件,可以后续使用open打开,在删除这个文件
In [8]: b=tempfile.mktemp("a.txt")
In [10]: b
Out[10]: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\tmpsf5u5xiua.txt'
# 创建有名字的临时文件
In [11]: f = tempfile.NamedTemporaryFile(delete=False)
In [12]: f.name
Out[12]: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\tmp8gj9s2o_'
In [13]: f.write(b'test')
Out[13]: 4
In [15]: import os
In [16]: os.path.exists(f.name)
Out[16]: True
In [17]: f.close()
In [18]: os.path.exists(f.name)
Out[18]: True
# 这个地方unlink下,他就被删除了
In [19]: os.unlink(f.name)
In [20]: os.path.exists(f.name)
Out[20]: False
11.7. glob¶
提供通配功能去查找文件的。
In [38]: glob.glob('*.zip')
Out[38]: ['backup.zip']
In [39]: glob.glob("**/*.txt",recursive=True)
Out[39]: ['2.txt', 'sub/3.txt']
11.8. fnmatch¶
此模块提供对Unix shell风格通配符的支持,这与正则表达式(在re模块中记录)不同。
模式 |
描述 |
---|---|
* |
任何的 |
? |
单个字符 |
[seq] |
集合里面的任何一个 |
[^seq] |
除了集合的任何一个 |
# 找到当前目录下的所有txt文件
import fnmatch
import os
for file in os.listdir('.'):
if fnmatch.fnmatch(file, '*.txt'):
print(file)
11.9. linecache¶
linecache模块允许从Python源文件中获取任何行,同时尝试使用缓存进行内部优化,这是 一种从单个文件中读取多行的常见情况。
In [40]: import linecache
In [41]: linecache.getline(linecache.__file__,8)
Out[41]: 'import functools\n'
11.10. shutil¶
这个模块提供高级别的文件操作,比较递归copy文件等。
shutil.copyfile(src, dst, *, follow_symlinks=True) 复制文件
shutil.copymode(src, dst, *, follow_symlinks=True) 复制mode
shutil.copystat(src, dst, *, follow_symlinks=True) 复制stat的atime,ctime,mtime信息
shutil.copy(src, dst, *, follow_symlinks=True) 复制文件,支持目录的
shutil.copy2(src, dst, *, follow_symlinks=True) 相比copy保留文件元数据信息
shutil.ignore_patterns(*patterns)
shutil.rmtree(path, ignore_errors=False, onerror=None) 删除目录
shutil.move(src, dst, copy_function=copy2) 移动文件或者目录
shutil.disk_usage(path) 磁盘使用情况
shutil.chown(path, user=None, group=None) 改变所有者,可以改组
shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None) 命令的路径
shutil.get_archive_formats() 获取归档格式
shutil.register_archive_format(name, function[, extra_args[, description]]) 注册归档格式
shutil.unregister_archive_format(name) 取消归档格式
shutil.unpack_archive(filename[, extract_dir[, format]]) 解压归档
shutil.unregister_unpack_format(name) 取消加压格式
shutil.get_terminal_size(fallback=(columns, lines)) 获取终端大小
使用样例:
# 复制src到dst目录,处理*.pyc和tmp*文件
from shutil import copytree, ignore_patterns
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
# 压缩文件
In [6]: make_archive("帮助文档","gztar","E:\\帮助文档")
Out[6]: 'C:\\Users\\Administrator\\帮助文档.tar.gz'
# 解压文件,可以不用指定格式,它内部自动根据扩展名字识别的
In [7]: from shutil import unpack_archive
In [8]: unpack_archive( 'C:\\Users\\Administrator\\帮助文档.tar.gz',"d:\\test")