Удалить старые файлы на полном диске - PullRequest
4 голосов
/ 22 марта 2012

Приложение, которое записывает данные на диск кусками по 100 МБ и увеличивает имя файла, добавляя +1, поэтому n1, n2 ... n1000.В конечном итоге это использует все свободное место на разделе (хост Linux).Я ищу способ удаления файлов, которые были впервые записаны в серии, пока дисковое пространство не будет использовано под конкретное использование.

Если последнее, https://stackoverflow.com/a/5912404/666891 будет хорошим решением?

Было предложено следующее решение, которое выглядит как жизнеспособное решение для https://stackoverflow.com/a/837840/666891. Как это можно изменить, чтобы обрабатывать увеличивающееся расширение файла, так как в настоящее время при запуске сценария он не удаляет файлы name filename *,звездочка, являющаяся инкрементным числом, начинать с самого старого?

import os
def free_space_up_to(free_bytes_required="161061273600", rootfolder="/data/", ex
tension="filename-*"):
    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())

1 Ответ

3 голосов
/ 02 апреля 2012

Что ж, если вы знаете, что все файлы имеют (по крайней мере, своего рода) размер 100 МБ, и при условии, что нет ничего более радикально изменяющего использование диска на машине, вам не нужно проверять свободное место на каждой итерации.1001 *

Кроме того, если все файлы имеют одинаковое имя, кроме счетчика в конце, вы можете пропустить вызов os.stat (который также может быть бесполезен для файлов, созданных в быстрой последовательности) и отсортировать имена файлов на основесчетчик:

import os

def free_space_up_to(free_bytes_required=161061273600, rootfolder="/data/", filesize=104857600, basename="filename-"):
    '''Deletes rootfolder/basename*, oldest first, until there are free_bytes_required available on the partition.
    Assumes that all files have file_size, and are all named basename{0,1,2,3,...}
    Returns number of deleted files.
    '''
    statv = os.statvfs(rootfolder)
    required_space = free_bytes_required - statv.f_bfree*statv.f_bsize
    basepath = os.path.join(rootfolder, basename)
    baselen = len(basepath)
    if required_space <= 0:
        return 0

    # "1 +" here for quickly rounding
    files_to_delete = 1 + required_space/filesize

    # List all matching files. If needed, replace with os.walk for recursively
    # searching into subdirectories of rootfolder
    file_list = [os.path.join(rootfolder, f) for f in os.listdir(rootfolder)
                 if f.startswith(basename)]

    file_list.sort(key=lambda i: int(i[baselen:]), reverse=True)
    # Alternatively, if the filenames can't be trusted, sort based on modification time
    #file_list.sort(key=lambda i: os.stat(i).st_mtime)

    for f in file_list[:files_to_delete]:
        os.remove(f)
    return files_to_delete

(не проверено полностью, я рекомендую выполнить пробный запуск, заменив "os.remove" на "print";))

...