Лучший способ получить список файлов в каталоге, отсортированный по дате добавления - PullRequest
0 голосов
/ 30 мая 2019

Я должен удалить самый старый файл в dir, когда самый новый добавленный файл превышает предел используемого пространства.Я не знаю, почему отсортированный список files = sorted(os.listdir(DIR), key=os.path.getctime) не содержит в первом элементе самый старый файл (в данном случае файл с именем 'file_1')

код

    print('START: Cycle no. ', cycle)
    time.sleep(1)
    print('Saving {0} files. {1} MB each'.format(FILES_NUM, MB_FILE_SIZE))
    i = 1
    while (i < FILES_NUM):
        usage = psutil.disk_usage(DIR)
        used = usage.used // (2**20)
        # print('Uzyta pamiec: ', used)
        if (used < 50): # 50 MB
            print('Saving file_{}'.format(i))
            with open("file_{}".format(i), 'wb') as f:
                f.write(os.urandom(FILE_SIZE))           
        else:
            files = sorted(os.listdir(DIR), key=os.path.getctime)
            print('Files list: ', files)
            os.remove(files[0])
            print('Deleted oldest file: ',files[0])
        i = i + 1

    print('KONIEC: Cycle no. ', cycle)
    print('Deleting the content of the card...')

результаты

Stress test results

РЕДАКТИРОВАТЬ: Я знаю, что следующийФайл после удаления должен иметь окончание в имени файла на единицу больше, чем в предыдущем добавлении.В этом примере должно быть Saving file_22 вместо Saving file_23.22-е «я» используется в процессе удаления, но как мне решить эту проблему?

1 Ответ

0 голосов
/ 30 мая 2019

Вы сортируете файлы по ctime не по алфавиту, поэтому не думайте, что самый старый файл будет file_1. Давайте посмотрим на это, используя упрощенную версию вашего кода:

import os
import sys

from datetime import datetime

FILES_NUM = 10
FILE_SIZE = 10


def main():
    for i in range(1, FILES_NUM + 1):
        if i == 5: # Assume disk usage has been exceeded
            files = sorted(os.listdir('.'), key=os.path.getctime)
            files = [
                f'{i} - {datetime.fromtimestamp(os.path.getctime(i))}'
                for i in files
                if i.startswith('file_')
            ]
            print(f'Files list: {files}')
            print(f'Deleted oldest file: {files[0]}')

        print(f'Saving file{i}')
        with open(f'file_{i}', 'wb') as f:
            f.write(os.urandom(FILE_SIZE))


if __name__ == '__main__':
    main()

Первый запуск (без файлов):

$ python test.py
Saving file1
Saving file2
Saving file3
Saving file4
Files list: ['file_1 - 2019-05-30 15:36:36.366754', 'file_2 - 2019-05-30 15:36:36.367754', 'file_4 - 2019-05-30 15:36:36.367754', 'file_3 - 2019-05-30 15:36:36.367754']
Deleted oldest file: file_1 - 2019-05-30 15:36:36.366754
Saving file5
Saving file6
Saving file7
Saving file8
Saving file9
Saving file10

Секунды запускаются (старые файлы уже существуют):

$ python test.py
Saving file1
Saving file2
Saving file3
Saving file4
Files list: ['file_6 - 2019-05-30 15:36:36.367754', 'file_5 - 2019-05-30 15:36:36.367754', 'file_7 - 2019-05-30 15:36:36.367754', 'file_8 - 2019-05-30 15:36:36.368754', 'file_10 - 2019-05-30 15:36:36.368754', 'file_9 - 2019-05-30 15:36:36.368754', 'file_1 - 2019-05-30 15:37:00.360535', 'file_2 - 2019-05-30 15:37:00.361535', 'file_4 - 2019-05-30 15:37:00.361535', 'file_3 - 2019-05-30 15:37:00.361535']
Deleted oldest file: file_6 - 2019-05-30 15:36:36.367754
Saving file5
Saving file6
Saving file7
Saving file8
Saving file9
Saving file10

Как вы видите, самый старый файл во время второго запуска - file_6. Это связано с тем, что, когда использование диска превышает пороговое значение, мы входим в ветку if, в которой мы сортируем и перечисляем существующие файлы, в этот момент были созданы только 1-4 файла, поэтому 5-10 еще старше.

Обратите также внимание, что ctime - это время последнего изменения метаданных в системах UNIX (владение файлом, права доступа, а не изменение содержимого). Вы можете попробовать mtime отсортировать по дате модификации.

Теперь проблема с индексами должна быть исправлена ​​после небольшого изменения логики в коде.

Примечание: пример использует Python 3.7 +

...