遇见一个删除文件的问题,网上的答案却都在扯淡?
关于文件(夹)的删除
之前的文章介绍过关于Python删除文件与文件夹的方式,在这里简单的复习下
删除文件的方法比较单一:
import os
os.remove(file)
而删除文件夹的时候,则有几种场景需要判断:
# path是文件夹路径,注意文件夹需要时空的才能被删除
os.rmdir(path)
# 通过os.walk,设置topdown=False,即可从叶子结点至根节点逐层删除
import os
for root, dirs, files in os.walk('D:\\software_temp', topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
# 通过shutil无脑删除
import shutil
shutil.rmtree('D:\\software_temp')
匪夷所思的问题
今天在写代码的时候,涉及到一个解压后删除多余文件的问题。然而,当执行os.remove(path)
的时候,却报错了,提示如下:
Traceback (most recent call last):
File "E:/remove_readonly_file.py", line 12, in <module>
os.remove('demo.txt')
PermissionError: [WinError 5] 拒绝访问。: 'demo.txt'
不知道大家是否和我的感觉一样,看到拒绝访问首先想到的是,这个文件被占用了,导致无法删除。然后检查代码是否存在未释放的进程。从头到尾review了代码,没有什么问题。
那上百度查查呗,结果千奇百怪的答案出来了,但总结下来都是说安装或者重装Python的时候,存在权限设置问题,需要修改Python.exe对User用户的权限。天真的我居然真的照着去做了,结局依然是没什么卵用。
嫁人要嫁程序员
有个笑话说,嫁人要嫁程序员,为什么?
因为他们无时无刻都在问自己,我错哪儿了,我到底错哪儿了,求求你告诉我,我改还不行吗?
只读属性
终于在无意间右键属性看了下文件,答案找到了,文件设置了只读属性。
获取文件属性
一直觉得Linux下的文件才会涉及到文件属性的问题,今天算是阴沟翻船了。那么Python如何获取文件的属性呢?来看看代码实现:
import os
os.stat('demo.txt')
# output
os.stat_result(st_mode=33060,
st_ino=2251799813692013,
st_dev=3223892962,
st_nlink=1,
st_uid=0,
st_gid=0,
st_size=0,
st_atime=1596983001,
st_mtime=1596981707,
st_ctime=1596981707)
这些返回的参数代表什么意思呢?
st_mode: inode 保护模式
st_ino: inode 节点号
st_dev: inode 驻留的设备
st_nlink: inode 的链接数
st_uid: 所有者的用户ID
st_gid: 所有者的组ID
st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据
st_atime: 上次访问的时间
st_mtime: 最后一次修改的时间
st_ctime: 文件创建时间
如果Linux使用多的朋友,不看注释都能猜到应该去找st_mode,但是这个mode的数字33060代表什么呢?
这么看是不就理解了:oct(33060) = '0o100444'
r代表4 w代表2 x代表1 咱们获取到的444,代表属主、属组、其他人权限均为只读。
上面的方式只是为了方便大家理解文件属性,但在实际的操作中,我们并不会通过该方式获取文件属性,而是使用下面的判断:
improt os
os.access(file,os.W_OK)
# os.F_OK: 检查文件或文件夹是否存在;
# os.R_OK: 检查文件或文件夹是否可读;
# os.W_OK: 检查文件或文件夹是否可以写入;
# os.X_OK: 检查文件或文件夹是否可以执行
修改文件属性
知道了文件的属性的查看,那么只需要对文件添加可写的属性,即可完成删除操作了。使用如下;
import os
import stat
# 增加写属性
os.chmod(file, stat.S_IWRITE)
# 取消写属性
os.chmod(file, stat.S_IWOTH)
那么,以后我们在删除文件的时候,执行如下操作,就更加稳妥了:
def judge_mode(path, file):
abs_file = os.path.join(path, file)
if not os.access(abs_file, os.W_OK):
os.chmod(abs_file, stat.S_IWOTH)
for root, dirs, files in os.walk('D:\\software_temp', topdown=False):
for file in files:
judge_mode(root, file)
os.remove(os.path.join(root, file))
for doc in dirs:
judge_mode(root, doc)
os.rmdir(os.path.join(root, doc))
网友评论