【问题标题】:Delete oldest files at full disk以全盘删除最旧的文件
【发布时间】:2012-03-22 02:35:04
【问题描述】:

一个将数据以 100MB 块写入磁盘并通过附加 +1 来增加文件名的应用程序,即n1, n2 ... n1000。这最终会使用分区(Linux 主机)上的所有可用空间。我正在寻找一种方法来删除系列中首次写入的文件,直到驱动器空间处于特定利用率之下。

如果是后者,https://stackoverflow.com/a/5912404/666891 会是一个好的解决方案吗?

提出了以下解决方案,并且看起来是每个https://stackoverflow.com/a/837840/666891 的可行解决方案。如何修改它以处理递增的文件扩展名,因为当前脚本运行时它不会删除文件名 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())

【问题讨论】:

  • 我相信您链接的 bash 脚本是一个很好的解决方案。
  • 您链接的脚本似乎删除了整个目录,而不是编号最小的文件。
  • 只有一个文件名前缀需要担心吗?例如n 或者您还需要考虑其他前缀吗?
  • 如果你决定走 python 路线,这可能会有所帮助。 stackoverflow.com/questions/837606/…
  • python 日志模块的RotatingFileHandler 已经完成了与 OP 要求类似的操作,但可能无法将现有代码转换为使用日志模块。

标签: python wrapper


【解决方案1】:

好吧,如果您知道所有文件的大小(至少在某种程度上)都是 100MB,并且假设没有其他任何东西会极大地改变机器上的磁盘使用情况,那么您无需在每次迭代时检查可用空间。

另外,如果所有文件都具有相同的名称,除了最后的计数器之外,您可以跳过 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

(未彻底测试,我建议用“print”替换“os.remove”;))

【讨论】:

  • 这就是我要找的。尝试运行它,将os.remove 更改为print 并且没有响应。还尝试更改 file_list.sort 以使用修改时间而没有任何改进。有什么想法或调试技巧吗?
  • 注意,如果需要的空间已经存在,则函数退出(返回0,即不需要删除文件)。在“return 0”之前放置一个打印语句,看看是否发生了这种情况。尝试将更大的数字传递给 free_bytes_required,以便该函数实际上需要删除一些文件。
  • return 0 之前添加了打印语句,但仍然没有输出,并且大小增加到大于可用空间的数量。还有其他调试技巧吗?
  • 嗯,你是怎么运行它的?我不知道你的Python知识是什么,但是如果你只是将上面的代码粘贴到一个文件中并执行“python file.py”,它不会执行该函数。您需要在文件末尾添加对函数的调用(不缩进),或者打开 Python 提示符,导入函数并手动执行。
  • 我正在调用该函数,但意识到需要调整文件大小。感谢您的洞察力和回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 2018-03-19
  • 2021-01-13
  • 1970-01-01
  • 2017-11-25
相关资源
最近更新 更多