gpt4 book ai didi

python - 这是使用 Python 获取文件名唯一版本的最佳方法吗?

转载 作者:太空狗 更新时间:2023-10-29 17:02:06 34 4
gpt4 key购买 nike

仍在“潜入”Python,并希望确保我没有忽略某些东西。我写了一个脚本,从几个 zip 文件中提取文件,并将提取的文件一起保存在一个目录中。为了防止重复的文件名被覆盖,我写了这个小函数——我只是想知道是否有更好的方法来做到这一点?谢谢!

def unique_filename(file_name):
counter = 1
file_name_parts = os.path.splitext(file_name) # returns ('/path/file', '.ext')
while os.path.isfile(file_name):
file_name = file_name_parts[0] + '_' + str(counter) + file_name_parts[1]
counter += 1
return file_name

我真的确实要求文件放在一个目录中,并且对我的情况进行重复编号绝对是可以接受的,所以我不是在寻找更可靠的方法(尽管我想任何欢迎指点),但只是为了确保以正确的方式完成这项工作。

最佳答案

一个问题是上面的代码中存在竞争条件,因为存在性测试与创建文件之间存在差距。这可能存在安全隐患(想想有人恶意插入一个符号链接(symbolic link)到一个他们无法覆盖的敏感文件,但你的程序以更高的权限运行可以)这样的攻击就是为什么像 os.tempnam( ) 已弃用。

要绕过它,最好的方法是实际尝试以这样一种方式创建文件:如果失败,您将获得异常,并在成功时返回实际打开的文件对象。这可以通过传递 os.O_CREAT 和 os.O_EXCL 标志来使用较低级别的 os.open 函数来完成。打开后,返回您创建的实际文件(以及可选的文件名)。例如,您的代码已修改为使用此方法(返回(文件,文件名)元组):

def unique_file(file_name):
counter = 1
file_name_parts = os.path.splitext(file_name) # returns ('/path/file', '.ext')
while 1:
try:
fd = os.open(file_name, os.O_CREAT | os.O_EXCL | os.O_RDRW)
return os.fdopen(fd), file_name
except OSError:
pass
file_name = file_name_parts[0] + '_' + str(counter) + file_name_parts[1]
counter += 1

[编辑] 实际上,可以为您处理上述问题的更好方法可能是使用 tempfile 模块,尽管您可能会失去对命名的一些控制。这是一个使用它的例子(保持相似的界面):

def unique_file(file_name):
dirname, filename = os.path.split(file_name)
prefix, suffix = os.path.splitext(filename)

fd, filename = tempfile.mkstemp(suffix, prefix+"_", dirname)
return os.fdopen(fd), filename

>>> f, filename=unique_file('/home/some_dir/foo.txt')
>>> print filename
/home/some_dir/foo_z8f_2Z.txt

这种方法的唯一缺点是您总是会得到一个包含一些随机字符的文件名,因为没有尝试先创建一个未修改的文件 (/home/some_dir/foo.txt)。您可能还想查看 tempfile.TemporaryFile 和 NamedTemporaryFile,它们将执行上述操作并在关闭时自动从磁盘中删除。

关于python - 这是使用 Python 获取文件名唯一版本的最佳方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/183480/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com