Hm. Ответ Нади ближе к тому, что вы хотели спросить; однако для поиска (одного) самого старого файла в дереве попробуйте следующее:
import os
def oldest_file_in_tree(rootfolder, extension=".avi"):
return min(
(os.path.join(dirname, filename)
for dirname, dirnames, filenames in os.walk(rootfolder)
for filename in filenames
if filename.endswith(extension)),
key=lambda fn: os.stat(fn).st_mtime)
С небольшой модификацией вы можете получить n
самые старые файлы (аналогично ответу Нади):
import os, heapq
def oldest_files_in_tree(rootfolder, count=1, extension=".avi"):
return heapq.nsmallest(count,
(os.path.join(dirname, filename)
for dirname, dirnames, filenames in os.walk(rootfolder)
for filename in filenames
if filename.endswith(extension)),
key=lambda fn: os.stat(fn).st_mtime)
Обратите внимание, что использование метода .endswith
разрешает вызовы как:
oldest_files_in_tree("/home/user", 20, (".avi", ".mov"))
для выбора более одного добавочного номера.
Наконец, если вам нужен полный список файлов, упорядоченный по времени модификации, чтобы удалить столько, сколько требуется для освобождения места, вот код:
import os
def files_to_delete(rootfolder, extension=".avi"):
return sorted(
(os.path.join(dirname, filename)
for dirname, dirnames, filenames in os.walk(rootfolder)
for filename in filenames
if filename.endswith(extension)),
key=lambda fn: os.stat(fn).st_mtime),
reverse=True)
и обратите внимание, что reverse=True
выводит самые старые файлы в конец списка, так что для удаления следующего файла вы просто делаете file_list.pop()
.
Кстати, для полного решения вашей проблемы, поскольку вы работаете в Linux, где доступен os.statvfs
, вы можете сделать:
import os
def free_space_up_to(free_bytes_required, rootfolder, extension=".avi"):
file_list= files_to_delete(rootfolder, extension)
while file_list:
statv= os.statvfs(rootfolder)
if statv.f_bfree*statv.f_bsize >= free_bytes_required:
break
os.remove(file_list.pop())
statvfs.f_bfree
- свободные блоки устройства, а statvfs.f_bsize
- размер блока. Мы берем rootfolder
statvfs, так что учтите любые символические ссылки, указывающие на другие устройства, где мы могли бы удалить много файлов, фактически не освобождая место на этом устройстве.
ОБНОВЛЕНИЕ (копирование комментария Хуана):
В зависимости от ОС и реализации файловой системы, вы можете умножить f_bfree на f_frsize, а не на f_bsize. В некоторых реализациях последний является предпочтительным размером запроса ввода-вывода. Например, в системе FreeBSD 9, которую я только что протестировал, f_frsize был 4096, а f_bsize был 16384. POSIX говорит, что поля счетчиков блоков «в единицах f_frsize» (см. http://pubs.opengroup.org/onlinepubs/9699919799//basedefs/sys_statvfs.h.html)