2012-03-22 13 views
3

ディスクにデータを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()) 
+0

私はあなたがリンクされbashスクリプトは良い解決策であると考えています。 – vascop

+0

リンク先のスクリプトは、最も番号の小さいファイルではなくディレクトリ全体を削除するように表示されます。 –

+0

心配するファイル名は1つだけですか?例えば ​​'n'や他のプレフィックスも考慮する必要がありますか? –

答えて

2

さてあなたはすべてのファイルのサイズは(少なくとも一種の)100メガバイト、およびマシン上のディスク使用量を変更すること大幅に他に何もないと仮定していることがわかっている場合、あなたはで空き領域をチェックする必要はありません。すべての反復。

また、すべてのファイルが同じ名前であれば、最後のカウンターのほかに、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」を代入するテストの実行をお勧めします;))

+0

それは私が探しているものです。 'os.remove'を' print'に変更して実行しようとしましたが、応答はありません。 'file_list.sort'を変更することなく、修正時間を使用してみました。任意のアイデアやデバッグのヒント? – Astron

+1

必要なスペースがすでに存在する場合、関数は終了します(0を返します。つまり、ファイルを削除する必要はありません)。 "return 0"の前にprintステートメントを置いて、これが起こっているかどうか確認してください。 free_bytes_requiredに大きな数値を渡してください。実際には、関数が実際にいくつかのファイルを削除する必要があります。 – rbp

+0

'return 0'の前にprintステートメントを追加しましたが、出力がなく、使用可能な空き容量よりも大きなサイズにサイズが増加しました。その他のデバッグのヒント? – Astron

関連する問題