Python 文件与文件夹操作


os模块

  • chdir(path) 把path设为当前工作目录
  • curdir 返回当前文件夹
  • environ 包含系统环境变量和值的字典
  • extsep 当前操作系统所使用的文件扩展名分隔符
  • get_exec_path() 返回可执行文件的搜索路径
  • getcwd() 返回当前工作目录
  • listdir(path) 返回path目录下的文件和目录列表
  • remove(path) 删除指定的文件,要求用户拥有删除文件的权限,并且文件没有只读或其他特殊属性
  • rename(src, dst) 重命名文件或目录,可以实现文件的移动,若目标文件已存在则抛出异常,不能跨越磁盘或分区
  • replace(old, new) 重命名文件或目录,若目标文件已存在则直接覆盖,不能跨越磁盘或分区
  • scandir(path=‘.’) 返回包含指定文件夹中所有DirEntry对象的迭代对象,遍历文件夹时比listdir()更加高效
  • sep 当前操作系统所使用的路径分隔符
  • startfile(filepath [, operation]) 使用关联的应用程序打开指定文件或启动指定应用程序
  • system() 启动外部程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
>>> import os
>>> import os.path
>>> os.rename('C:\\dfg.txt',
'D:\\test2.txt') #rename()可以实现文件的改名和移动
>>> [fname for fname in os.listdir('.')if fname.endswith(('.pyc','.py','.pyw'))] #结果略
>>> os.getcwd() #返回当前工作目录'C:\\Python35'
>>> os.mkdir(os.getcwd()+'\\temp') #创建目录
>>> os.makedirs(os.getcwd()+'\\temp', exist_ok=True)
#可以递归创建
>>> os.chdir(os.getcwd()+'\\temp') #改变当前工作目录
>>> os.getcwd()
'C:\\Python35\\temp'
>>> os.mkdir(os.getcwd()+'\\test')
>>> os.listdir('.')
['test']
>>> os.rmdir('test') #删除目录
>>> os.listdir('.')
[]
>>> os.environ.get('path') #获取系统变量path的值
>>> import time
>>> time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.stat('yilaizhuru2.py').st_ctime))#查看文件创建时间
'2016-10-18 15:58:57'
>>> os.startfile('notepad.exe') #启动记事本程序
```python

### os.path模块

* **abspath(path) 返回给定路径的绝对路径**
* basename(path) 返回指定路径的最后一个组成部分
* commonpath(paths) 返回给定的多个路径的最长公共路径
* commonprefix(paths) 返回给定的多个路径的最长公共前缀
* **dirname§ 返回给定路径的文件夹部分**
* **exists(path) 判断文件是否存在**
* getatime(filename) 返回文件的最后访问时间
* getctime(filename) 返回文件的创建时间
* getmtime(filename) 返回文件的最后修改时间
* **getsize(filename) 返回文件的大小**
* **isabs(path) 判断path是否为绝对路径**
* **isdir(path) 判断path是否为文件夹**
* **isfile(path) 判断path是否为文件**
* \**join(path, *paths) 连接两个或多个path**
* **realpath(path) 返回给定路径的绝对路径**
* **relpath(path) 返回给定路径的相对路径,不能跨越磁盘驱动器或分区**
* samefile(f1, f2) 测试f1和f2这两个路径是否引用的同一个文件
* **split(path) 以路径中的最后一个斜线为分隔符把路径分隔成两部分,以元组形式返回**
* **splitext(path) 从路径中分隔文件的扩展名**
* splitdrive(path) 从路径中分隔驱动器的名称

```python
>>> path=
'D:\\mypython_exp\\new_test.txt'
>>> os.path.dirname(path) #返回路径的文件夹名'D:\\mypython_exp'
>>> os.path.basename(path) #返回路径的最后一个组成部分'new_test.txt'
>>> os.path.split(path) #切分文件路径和文件名('D:\\mypython_exp','new_test.txt')
>>> os.path.split('') #切分结果为空字符串
('','')
>>> os.path.split('C:\\windows') #以最后一个斜线为分隔符
('C:\\','windows')
>>> os.path.split('C:\\windows\\')
('C:\\windows','')
>>> os.path.splitdrive(path) #切分驱动器符号
('D:','\\mypython_exp\\new_test.txt')
>>> os.path.splitext(path) #切分文件扩展名
('D:\\mypython_exp\\new_test',='.txt')
```python

##### 使用递归法遍历指定目录下所有子目录和文件。

```python
from os import listdir
from os.path import join, isfile, isdir
def listDirDepthFirst(directory):
'''深度优先遍历文件夹'''
#遍历文件夹,如果是文件就直接输出
#如果是文件夹,就输出显示,然后递归遍历该文件夹
for subPath in listdir(directory):
path = join(directory, subPath)
if isfile(path):
print(path)
elif isdir(path):
print(path)
listDirDepthFirst(path)
```python

### shutil模块

* **copy(src, dst) 复制文件,新文件具有同样的文件属性,如果目标文件已存在则抛出异常**
* copy2(src, dst) 复制文件,新文件具有原文件完全一样的属性,包括创建时间、修改时间和最后访问时间等等,如果目标文件已存在则抛出异常
* **copyfile(src, dst) 复制文件,不复制文件属性,如果目标文件已存在则直接覆盖**
* copyfileobj(fsrc, fdst) 在两个文件对象之间复制数据,例如

```python
copyfileobj(open('123.txt'),open('456.txt','a'))
```python
* copymode(src, dst) 把src的模式位(mode bit)复制到dst上,之后二者具有相同的模式
* copystat(src, dst) 把src的模式位、访问时间等所有状态都复制到dst上
* **copytree(src, dst) 递归复制文件夹**
* disk\_usage(path) 查看磁盘使用情况
* **move(src, dst) 移动文件或递归移动文件夹,也可以给文件和文件夹重命名**
* **rmtree(path) 递归删除文件夹**
* **make\_archive(base\_name,format, root\_dir=None,base\_dir=None) 创建tar或zip格式的压缩文件**
* **unpack\_archive(filename,extract\_dir=None,format=None) 解压缩压缩文件**

#### 使用例

**如何使用标准库shutil的copyfile()方法复制文件**

```python
>>> import shutil #导入shutil模块
>>> shutil.copyfile('C:\\dir.txt','C:\\dir1.txt') #复制文件
```python

**将C:\Python35\Dlls文件夹以及该文件夹中所有文件压缩至D:\a.zip文件:**

```python
>>> shutil.make_archive('D:\\a','zip','C:\\Python35',
'Dlls')
'D:\\a.zip'
```python

**将刚压缩得到的文件D:\a.zip解压缩至D:\a\_unpack文件夹:**

```python
>>> shutil.unpack_archive('D:\\a.zip','D:\\a_unpack')
```python

**下面的代码使用shutil模块的方法删除刚刚解压缩得到的文件夹**

```python
>>> shutil.rmtree('D:\\a_unpack')
```python

**码使用shutil的copytree()函数递归复制文件夹,并忽略扩展名为pyc的文件和以“新”字开头的文件和子文件夹:**

```python
>>> from shutil import copytree, ignore_patterns
>>> copytree('C:\\python35\\test','D:\\des_test'ignore=ignore_patterns('*.pyc','新*'))
```python

### 实践

##### 把指定文件夹中的所有文件名批量随机化,保持文件类型不变。

```python
from string import ascii_letters
from os import listdir, rename
from os.path import splitext, join
from random import choice, randint
def randomFilename(directory):
for fn in listdir(directory):
#切分,得到文件名和扩展名
name, ext = splitext(fn)
n = randint(5, 20)
#生成随机字符串作为新文件名
newName = ''.join((choice(ascii_letters) for i in range(n)))
#修改文件名
rename(join(directory, fn), join(directory, newName+ext))
randomFilename('C:\\test')
```python

##### 编写程序,统计指定文件夹大小以及文件和子文件夹数量。

```python
import os
totalSize = 0
fileNum = 0
dirNum = 0
def visitDir(path):
global totalSize
global fileNum
global dirNum
for lists in os.listdir(path):
sub_path = os.path.join(path, lists)
if os.path.isfile(sub_path):
fileNum = fileNum+1 #统计文件数量
totalSize = totalSize+os.path.getsize(sub_path) #统计文件总大小
elif os.path.isdir(sub_path):
dirNum = dirNum+1 #统计文件夹数量
visitDir(sub_path) #递归遍历子文件夹

def main(path):
if not os.path.isdir(path):
print('Error:"', path,'" is not a directory or does notexist.')
return
visitDir(path)
def sizeConvert(size): #单位换算
K, M, G = 1024, 1024**2, 1024**3
if size >= G:
return str(size/G)+'G Bytes'
elif size >= M:
return str(size/M)+'M Bytes'
elif size >= K:
return str(size/K)+'K Bytes'
else:
return str(size)+'Bytes'

def output(path):
print('The total size of '+path+' is:'+sizeConvert(totalSize)+'('+str(totalSize)+' Bytes)')
print('The total number of files in '+path+' is:',fileNum)
print('The total number of directories in '+path+' is:',dirNum)
if __name__=='__main__':
path = 'C:\\text_dir'
main(path)
output(path)
```python

##### 编写程序,递归删除指定文件夹中指定类型的文件和大小为0的文件。

```python
from os.path import isdir, join, splitext
from os import remove, listdir, chmod, stat
filetypes = ('.tmp', '.log', '.obj', '.txt') #指定要删除的文件类型
def delCertainFiles(directory):
if not isdir(directory):
return
for filename in listdir(directory):
temp = join(directory, filename)
if isdir(temp):
delCertainFiles(temp) #递归调用
elif splitext(temp)[1] in filetypes or stat(temp).st_size==0:
chmod(temp, 0o777) #修改文件属性,获取删除权限
remove(temp) #删除文件
print(temp, ' deleted....')
delCertainFiles(r'C:\test')

Author: BY 水蓝
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source BY 水蓝 !
  TOC