按順序檢查每個文件名以查找下一個可用的文件名,可以使用少量文件正常工作,但隨着文件數量的增加,文件名會迅速變慢。
下面是日誌(n)時間內找到下一個可用的文件名的版本:
import os
def next_path(path_pattern):
"""
Finds the next free path in an sequentially named list of files
e.g. path_pattern = 'file-%s.txt':
file-1.txt
file-2.txt
file-3.txt
Runs in log(n) time where n is the number of existing files in sequence
"""
i = 1
# First do an exponential search
while os.path.exists(path_pattern % i):
i = i * 2
# Result lies somewhere in the interval (i/2..i]
# We call this interval (a..b] and narrow it down until a + 1 = b
a, b = (i/2, i)
while a + 1 < b:
c = (a + b)/2 # interval midpoint
a, b = (c, b) if os.path.exists(path_pattern % c) else (a, c)
return path_pattern % b
爲了測量速度提高我寫了創建10,000個文件一個小的測試功能:
for i in range(1,10000):
with open(next_path('file-%s.foo'), 'w'):
pass
並實現了原始的方法:
def next_path_naive(path_pattern):
"""
Naive (slow) version of next_path
"""
i = 1
while os.path.exists(path_pattern % i):
i += 1
return path_pattern % i
而且這裏的結果:
快速版本:
real 0m2.132s
user 0m0.773s
sys 0m1.312s
天真的版本:
real 2m36.480s
user 1m12.671s
sys 1m22.425s
最後,請注意,這兩種方法是容易受到競爭情況,如果多個演員都試圖在同一時間創建序列中的文件。
這裏'format()'方法比字符串連接更清晰。我認爲while循環很好,在這裏。在另一個話題上,爲什麼使用'abspath()'? – EOL
格式更清晰,但他必須查看字符串格式;乍看之下,這很容易理解。和abspath,因爲我忽略符號鏈接:/ ....可能導致混淆錯誤 –
雖然我明白你的觀點,但我相信即使是初學者也應該顯示Pythonic的例子,以便他們養成良好的習慣。 'format()'的行爲真的很容易理解,甚至猜測:'「{} {} .py」.format(filename,filenum)'。它比這裏介紹的算法更簡單。 :) – EOL