簡體   English   中英

使用 python 從特定日期開始讀取目錄中的文件

[英]Read files in a directory starting by a specific date using python

我有一個自動化的過程,需要對文件執行一些操作。 另一個進程創建這些文件並將它們存儲在一個目錄中,我只需要處理最近的文件,但必須將這些文件保留在那里並且永遠不要刪除它們,因為我認為該進程開始使用大量文件獲得所需文件時的資源。

我最初的想法是創建另一個進程,將最新的文件(為了確保額外的一天)復制到另一個文件夾,但我只是想知道(或者我確定呵呵)是否有更好的方法來獲取這些文件而無需閱讀所有這些,或者我的代碼是否可以優化。

我的主要問題是,當我到達這部分代碼時,服務器的 CPU 使用率正在獲取圖表,我假設在某些時候該進程會由於某些操作系統錯誤而中斷。 我只需要獲取所需文件的名稱,即創建日期大於我使用的最后一個文件的名稱,每次我對文件執行操作時,該名稱都會轉到數據庫中的表中我得到最后一個文件的名稱。 我的問題不在於查詢或執行的操作,CPU 使用率最低,只是我讀取所有文件並比較它們的日期並將它們添加到數組的這一部分。

這是我的代碼(如果它很可怕,請不要生氣)重載在 for 之后開始:

def get_ordered_files():
    valid_files = []
    epoch = datetime.datetime.utcfromtimestamp(0)
    get_last_file = check_last_successful_file()
    last_date = os.path.getctime(get_last_file)
    files = glob.glob(files_location + file_extension)
    files.sort(key=os.path.getctime, reverse=False)
    for single_file in files:
        total_days_file = datetime.datetime.fromtimestamp(os.path.getctime(single_file)) - epoch
        total_days_last = datetime.datetime.fromtimestamp(last_date) - epoch
        if total_days_file.total_seconds() > total_days_last.total_seconds():
            check_empty = get_email_account(single_file)
            if check_empty != "" and check_empty is not None:
                valid_files.append(single_file)
    return valid_files

非常感謝您的所有幫助(我使用的是 python 3.8)。

您的代碼中有很多冗余操作。

例如,使用fromtimestamp()在循環內計算total_days_last可以簡單地在循環外完成一次。 事實上,使用datetime函數和使用epoch似乎沒有必要,因為您可以直接比較文件ctime值。

os.path.getctime()在每個文件上調用兩次:一次用於排序,第二次用於計算total_days_file

這些對大量文件的重復計算將成為性能問題的一部分。

另一個問題是,如果有大量文件,列表files可能會變得非常大,需要大量的 memory。

if check_empty:= "" and check_empty is not None:可以簡單地寫成if check_empty:

這是一個簡化版本:

def get_ordered_files():
    last_ctime = os.path.getctime(check_last_successful_file())
    files = glob.glob(files_location + file_extension)
    files.sort(key=os.path.getctime)
    return [f for f in files
                if os.path.getctime(f) > last_ctime and get_email_account(f)]

這消除了大部分冗余代碼,但仍然為每個文件調用os.path.getctime()兩次。 為了避免這種情況,我們可以在第一次獲得每個文件時存儲它的ctime

pattern = os.path.join(files_location, file_extension)

def get_ordered_files():
    last_ctime = os.path.getctime(check_last_successful_file())
    files = ((filename, ctime) for filename in glob.iglob(pattern)
                if (ctime := os.path.getctime(filename)) > last_ctime and
                    get_email_account(filename))
    return (filename for filename, _ in sorted(files, key=itemgetter(1)))

這里將生成器表達式分配給files 它使用glob.iglob() ,它是glob.glob() () 的迭代器版本,它不會一次存儲所有文件。 文件名及其 ctime 值都存儲為元組。 生成器表達式過濾掉太舊的文件和沒有關聯 email 帳戶的文件。 最后返回另一個生成器,按 ctime 對文件進行排序。 然后調用代碼可以遍歷生成器,或者在其上調用list()以將其實現為列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM